RDF (Resource Description Framework) is the W3C’s data model for describing things and their relationships as a graph of statements. It defines what a statement is, what identifiers and values may appear in one, and how statements combine into graphs and datasets. It is a model, not a file format, and can be written in several syntaxes that all mean the same thing.
The acronym is ambiguous outside this field: .rdf is also a file extension (usually holding RDF/XML), and RDF stands for radial distribution function in chemistry and random decision forest in machine learning. This page is about the W3C data model.
The triple, in brief
An RDF statement is a triple: a subject, a predicate, and an object. “Eiffel Tower, located in, Paris” is one. Each triple is a directed labeled edge, and triples connect when one triple’s object appears as another’s subject, which is how RDF forms a graph. The positions and their rules are covered at triples: subject, predicate, object.
The RDF data model
Four kinds of thing appear in a triple, and the model is little more than the rules governing them.
IRIs. An IRI (Internationalized Resource Identifier) is a global name, the internationalized form of a URI. http://www.wikidata.org/entity/Q243 names the Eiffel Tower; https://schema.org/location names a property. IRIs may fill any position and need not resolve to a document, although linked data conventions say they should. Two graphs describe the same thing whenever they use the same IRI, which is the source of RDF’s merge behavior.
Literals. A literal is a concrete value with a lexical form (a string) and a datatype IRI, usually an XML Schema datatype: "330"^^xsd:decimal, "1889-03-31"^^xsd:date, "true"^^xsd:boolean. A literal may instead carry a language tag, making its datatype rdf:langString: "Eiffel Tower"@en. Written with neither, it is xsd:string. Literals appear only as objects, because a value cannot hold properties of its own.
Blank nodes. A blank node has no global identifier and exists only within the graph containing it. It stands for something that exists but need not be named: a postal address, a measurement, a list cell. Labels such as _:b0 are local to a document, so two files using _:b0 describe different nodes. Blank nodes may be subjects or objects, never predicates.
Graphs and datasets. An RDF graph is a set of triples. An RDF dataset is one default graph plus zero or more named graphs, each paired with an identifying IRI; a triple with its graph name is a quad. Named graphs are how a store tracks provenance (these triples came from Wikidata, those from an internal system), scopes access control, or deletes one source in a single operation.
What RDF is for
RDF exists so that data produced independently can be combined without prior agreement about structure. Merging two relational databases means reconciling table layouts, column names, keys and cardinality. Merging two RDF graphs is set union: nothing needs to agree except identifiers. Where both sides used wd:Q243, their statements land on the same node.
Three consequences follow: schema is additive (a new property is a new triple, not a migration), vocabularies mix (schema.org, Dublin Core and a house vocabulary can coexist in one graph), and identity is explicit rather than positional, so a statement keeps its meaning when copied out of its file.
Specification history and current state
RDF became a W3C Recommendation in February 1999 and was substantially revised in February 2004, the version usually called RDF 1.0. RDF 1.1 followed in February 2014 and is what most tooling targets: it made IRIs rather than URIs the identifier, gave every literal a datatype, defined datasets and named graphs, and standardized Turtle, TriG, N-Triples and N-Quads alongside RDF/XML.
Work on RDF 1.2 is in progress at the W3C. Its central addition is the RDF-star work, which lets a triple be referenced as the subject or object of another triple, so statements can carry provenance, time or confidence without reification. SPARQL 1.2 is being developed in parallel, and Apache Jena, Oxigraph, GraphDB and Stardog already implement forms of the proposal.
One graph, six serializations
The graph below is used in every example that follows: the Eiffel Tower is a landmark, has English and French labels, is located in Paris, is 330 metres high, and has an address given as a blank node. Paris carries one label.
Turtle
Turtle (Terse RDF Triple Language) is the format to write by hand and to read. It declares prefixes, ends each statement with a period, and offers two abbreviations: a semicolon repeats the subject, a comma repeats subject and predicate. Square brackets write a blank node inline, and a means rdf:type.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix schema: <https://schema.org/> .
@prefix wd: <http://www.wikidata.org/entity/> .
wd:Q243 a schema:LandmarksOrHistoricalBuildings ;
rdfs:label "Eiffel Tower"@en , "Tour Eiffel"@fr ;
schema:location wd:Q90 ;
schema:height "330"^^xsd:decimal ;
schema:address [ a schema:PostalAddress ;
schema:addressLocality "Paris" ;
schema:postalCode "75007" ] .
wd:Q90 rdfs:label "Paris"@en .
N-Triples
N-Triples writes one triple per line with absolute IRIs in angle brackets, no prefixes and no abbreviations. Every line parses independently, so a file can be split at any newline and handed to any number of workers. That makes it the standard format for bulk dumps and streaming.
<http://www.wikidata.org/entity/Q243> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://schema.org/LandmarksOrHistoricalBuildings> .
<http://www.wikidata.org/entity/Q243> <http://www.w3.org/2000/01/rdf-schema#label> "Eiffel Tower"@en .
<http://www.wikidata.org/entity/Q243> <http://www.w3.org/2000/01/rdf-schema#label> "Tour Eiffel"@fr .
<http://www.wikidata.org/entity/Q243> <https://schema.org/location> <http://www.wikidata.org/entity/Q90> .
<http://www.wikidata.org/entity/Q243> <https://schema.org/height> "330"^^<http://www.w3.org/2001/XMLSchema#decimal> .
<http://www.wikidata.org/entity/Q243> <https://schema.org/address> _:b0 .
_:b0 <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <https://schema.org/PostalAddress> .
_:b0 <https://schema.org/addressLocality> "Paris" .
_:b0 <https://schema.org/postalCode> "75007" .
<http://www.wikidata.org/entity/Q90> <http://www.w3.org/2000/01/rdf-schema#label> "Paris"@en .
JSON-LD
JSON-LD expresses RDF as ordinary JSON, with a @context mapping keys to predicate IRIs. It is the format search engines read on web pages. @id supplies a subject, @type produces an rdf:type triple, a nested object without @id is a blank node, and @value with @type or @language writes a typed or tagged literal. Full details: JSON-LD.
{
"@context": "https://schema.org",
"@id": "http://www.wikidata.org/entity/Q243",
"@type": "LandmarksOrHistoricalBuildings",
"name": [
{ "@value": "Eiffel Tower", "@language": "en" },
{ "@value": "Tour Eiffel", "@language": "fr" }
],
"location": { "@id": "http://www.wikidata.org/entity/Q90" },
"height": { "@value": "330", "@type": "http://www.w3.org/2001/XMLSchema#decimal" },
"address": {
"@type": "PostalAddress",
"addressLocality": "Paris",
"postalCode": "75007"
}
}
RDF/XML
RDF/XML was the original syntax and the only normative one in 1999, which is why .rdf files usually contain it and why “RDF” and “XML” became conflated. Older tooling still emits it, but few projects choose it: the mapping from graph to XML tree admits several equivalent shapes, and the result is hard to read.
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:schema="https://schema.org/">
<rdf:Description rdf:about="http://www.wikidata.org/entity/Q243">
<rdf:type rdf:resource="https://schema.org/LandmarksOrHistoricalBuildings"/>
<rdfs:label xml:lang="en">Eiffel Tower</rdfs:label>
<rdfs:label xml:lang="fr">Tour Eiffel</rdfs:label>
<schema:location rdf:resource="http://www.wikidata.org/entity/Q90"/>
<schema:height rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal">330</schema:height>
</rdf:Description>
</rdf:RDF>
TriG and N-Quads
TriG is Turtle extended with graph names: a block of triples in braces, labeled by an IRI. N-Quads is N-Triples with a fourth term per line. Both serialize a dataset rather than a single graph, so provenance survives export and reload.
@prefix schema: <https://schema.org/> .
@prefix wd: <http://www.wikidata.org/entity/> .
<http://example.org/graph/wikidata-import> {
wd:Q243 schema:location wd:Q90 .
}
<http://www.wikidata.org/entity/Q243> <https://schema.org/location> <http://www.wikidata.org/entity/Q90> <http://example.org/graph/wikidata-import> .
Notation3 (N3), from which Turtle was carved, and RDF/JSON, an early JSON encoding predating JSON-LD, still appear in older documents and libraries. Neither is a current choice.
Serialization comparison
| Format | Human-readable | Line-streamable | Named graphs | Media type | Typical use |
|---|---|---|---|---|---|
| Turtle | Yes | No | No | text/turtle | Hand-authoring, examples, ontologies |
| N-Triples | Poor | Yes | No | application/n-triples | Dumps, streaming, diffing, canonical form |
| JSON-LD | Yes | No | Yes (@graph) | application/ld+json | Web pages, APIs, application code |
| RDF/XML | Poor | No | No | application/rdf+xml | Legacy files and tooling |
| TriG | Yes | No | Yes | application/trig | Hand-authoring datasets |
| N-Quads | Poor | Yes | Yes | application/n-quads | Dataset dumps and loads |
“Line-streamable” means each line stands alone, so a file can be read, appended to and split without parsing the whole document. That is why large public dumps ship as N-Triples or N-Quads, and why bulk graph data travels as JSONL.
Content negotiation
Because one graph has many syntaxes, RDF servers pick a format from the client’s Accept header, using the media types above. A request for http://www.wikidata.org/entity/Q243 with Accept: text/turtle returns Turtle; with Accept: application/ld+json it returns JSON-LD. This is how one IRI serves both a browser and a machine, and it is the mechanism behind dereferenceable identifiers.
The vocabularies RDF ships with
RDF defines a small vocabulary in the rdf: namespace: rdf:type states class membership, rdf:Property is the class of properties, rdf:value is a convention for the main value of a structured node, and rdf:langString types language-tagged literals.
Ordered data uses rdf:List, built from rdf:first and rdf:rest cells terminated by rdf:nil. Each cell is a blank node holding one item and a pointer to the remainder, so a three-item list is nine triples. Turtle hides this behind parentheses: ( wd:Q90 wd:Q64 wd:Q84 ) expands to the chain. Lists are exact but awkward to query, so many graphs use an index property instead.
RDFS (RDF Schema) sits directly on top, adding rdfs:Class, rdfs:subClassOf, rdfs:subPropertyOf, rdfs:domain, rdfs:range, rdfs:label and rdfs:comment, enough to declare a taxonomy and let a reasoner infer types up the hierarchy. Cardinality and disjointness need OWL. See ontologies.
Tooling
Python uses rdflib, which parses and serializes every format above and runs SPARQL in process. On the JVM, Apache Jena and Eclipse RDF4J are the mature stacks, each with parsers, an in-memory model, a persistent store and a SPARQL engine. Oxigraph is a Rust store with Python bindings, useful when rdflib is too slow. For command-line conversion, Jena ships riot and Raptor ships rapper.
from rdflib import Graph
g = Graph()
g.parse("eiffel.ttl", format="turtle")
g.serialize(destination="eiffel.nt", format="nt")
print(len(g), "triples")
RDF is queried with SPARQL and validated with SHACL. For building a graph end to end, see knowledge graph in Python.
For developers
Pick N-Triples or N-Quads for anything at volume and Turtle for anything a person will read. Set datatypes on every non-text literal at write time; stringly typed numbers will not sort or filter correctly, and fixing them later means rewriting the data. Treat blank nodes as deliberate: right for structured values with no independent identity, wrong for anything another dataset might reference. Canonicalize before comparing two graphs (sorted N-Triples is the cheap approximation). RDF also has no record boundaries, so deleting “an object” means deleting the triples known to describe it, one reason to use named graphs.
For SEOs
Every JSON-LD block on a page is RDF, and that fact explains most of the format’s behavior. @id exists because RDF subjects are IRIs, so two pages describing the same organization without a shared @id produce two unrelated nodes, however identical their name values. sameAs works because it asserts an IRI-to-IRI equivalence a consumer can follow to Wikidata, which is how a node in a site’s markup attaches to one in the Google Knowledge Graph. And values must be the right kind of node: address expects a PostalAddress node with its own triples, so a plain string is a type error in the model. See sameAs schema and structured data.
Common misconceptions
“RDF is an XML format.” RDF/XML was the first syntax and left a permanent impression. RDF is an abstract model; Turtle, N-Triples, JSON-LD, TriG, and N-Quads are equally conformant, and RDF/XML is now the least used.
“RDF is a database.” RDF specifies a model and its syntaxes, nothing about storage, indexing, or transactions. The triple stores that implement it (Apache Jena TDB, RDF4J, GraphDB, Stardog, Virtuoso, Blazegraph, Amazon Neptune, Oxigraph) differ from each other as much as relational engines do.
“RDF is inherently slower than a property graph.” The model does not set performance. A triple store with good indexes answers pattern queries at speeds comparable to a labeled property graph (LPG) engine on the same hardware. See property graph vs RDF.
Related pages
FAQ
What is RDF?
RDF (Resource Description Framework) is a W3C data model for describing things as a graph of subject-predicate-object statements called triples. Subjects and predicates are IRIs; objects are IRIs, blank nodes or typed literals. RDF is a model rather than a file format, so one graph can be written in Turtle, N-Triples, JSON-LD, RDF/XML, TriG or N-Quads.
What is the difference between Turtle and N-Triples?
Both write the same triples. Turtle allows prefixes, semicolon and comma shorthand, inline blank nodes and list syntax, which makes it compact for hand-authoring. N-Triples allows none of these: one triple per line with absolute IRIs. That restriction is the point, since every line parses independently, so N-Triples suits dumps and streaming.
Which RDF version is current?
RDF 1.1 (February 2014) is the current set of W3C Recommendations and what tooling targets. RDF 1.2 is under development at the W3C; its main addition is RDF-star, which lets you make statements about statements, with SPARQL 1.2 alongside it. Several triple stores already support RDF-star syntax ahead of the finished specification.
Sources and further reading
- RDF 1.1 Concepts and Abstract Syntax: https://www.w3.org/TR/rdf11-concepts/
- RDF 1.1 Primer: https://www.w3.org/TR/rdf11-primer/
- RDF 1.1 Turtle: https://www.w3.org/TR/turtle/
- RDF 1.1 N-Triples: https://www.w3.org/TR/n-triples/
- RDF 1.1 TriG: https://www.w3.org/TR/trig/
- RDF Schema 1.1: https://www.w3.org/TR/rdf-schema/
- rdflib documentation: https://rdflib.readthedocs.io/
