The execution of SPARQL queries can be challenging for a number of reasons
including performance, availability, and reproducibility.
To encourage greater reproducibility, sharability, and performance of these queries, a result caching approach offers a pragmatic solution.
This specification defines SPARQL Query View Materialization Containers (QVMC):
HTTP resources that implement the Linked Data Platform (LDP) Container model to store SPARQL query definitions and their corresponding materialized result sets.
A QVMC is an ldp:BasicContainer
whose members include SPARQL query source files
and SPARQL Results documents.
An RDF index resource describes the contained views and how they were generated.
These guidelines enable clients and tools to reliably leverage cached SPARQL queries, their canonical
algebra, provenance, and serialized results, in a way that promotes interoperability and reuse.
This document discusses the canonical view materialization of SPARQL queries and results. This document is primarily intended for the following audiences:
The goals of this specification are to:
queries.ttl
— an RDF index that inventories the views in a container and
captures provenance.
To understand the basics in this note ... (knowledge requirements)
The SPARQL Query Cache (SQC) is a conventional layout for
representing cached SPARQL queries and their results as HTTP resources
inside an ldp:Container
. Each cached query is addressed by
a stable, opaque identifier derived from a cache key function over the
query text, dataset/endpoint selection, and selected request headers.
The cache also stores a canonical SPARQL algebra form and a serialized
result set for deterministic reuse.
Key terms are used as defined in the following specifications: Linked Data Platform (LDP), SPARQL 1.1 Query, SPARQL Results JSON and XML.
queries.ttl
at the root of a QVMC.RFC 2119 keywords (MUST, SHOULD, MAY) indicate conformance requirements.
The following prefixes are used throughout the document.
PREFIX rdfs: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . PREFIX prov: <http://www.w3.org/ns/prov#> . PREFIX dc: <http://purl.org/dc/terms/> . PREFIX sh: <http://www.w3.org/ns/shacl#> . PREFIX tq: <http://www.w3.org/2001/sw/DataAccess/tests/test-query#> . PREFIX tm: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . PREFIX sd: <http://www.w3.org/ns/sparql-service-description#> . PREFIX se: <https://purl.expasy.org/sparql-examples/ontology#> . PREFIX qvmc: <https://vocab.example/qvmc#> .
A SPARQL query execution, from the perspective of the user, consists of four distinct componenets.
A QVMC MUST be an HTTP-accessible ldp:BasicContainer
and MUST advertise Link: <http://www.w3.org/ns/ldp#BasicContainer> ; rel="type"
in responses to GET
on the container URI.
Servers SHOULD also include ldp:contains
statements in RDF representations.
The members of a QVMC are:
queries.ttl
(text/turtle
)..rq
and media type application/sparql-query
..srj
(application/sparql-results+json
) or
.srx
(application/sparql-results+xml
).Additional non-normative artifacts (e.g., CSV extracts) MAY be present but are out of scope.
{container}/queries.ttl
.{hash}
token to bind each query entry to its query SPARQL algebra and results files (details below).{container}/{hash}.rq
.{container}/{hash}.{srj|srx}
.GET /views/ HTTP/1.1 Accept: text/turtle HTTP/1.1 200 OK Link: <http://www.w3.org/ns/ldp#BasicContainer> ; rel="type" Content-Type: text/turtle; charset=utf-8 @prefix ldp: <http://www.w3.org/ns/ldp#> . @prefix dc: <http://purl.org/dc/terms/> . @prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . a ldp:BasicContainer ; dc:title "SPARQL Query Materialization Container" ; ldp:contains </views/queries.ttl> , </views/hash1.rq> , </views/hash1.srj> , # ... more members ... .
The container includes an index file, queries.ttl
, which is a Turtle graph that describes each stored SPARQL query entry using terms from SPARQL 1.1, SHACL, and Service Description.
The following classes and properties are used:
tq:QueryForm
— a materialized view entry.dct:title
, dct:description
, dct:modified
— human-readable metadata.tq:QuerySelect
— the supported SPARQL query operation.sh:SPARQLExecutable
- designates that this hash contains a link to the .rq
file.tq:query
(IRI) — link to the .rq
file.sh:select
(literal) — the entry's SPARQL query algebra (identical to that in the entry's .rq file).tm:result
(IRI) — link to the .srj
or .srx
file.sd:endpoint
(IRI) — link to the RDF list containing the target sources of the query entry (sources must be valid URIs).dct:created
(xsd:dateTime) — timestamp of when the query was executed.qvmc:status
(literal; values: current
| stale
| failed
) — indicates the current state of the query entry results.prov:wasGeneratedBy
— blank node with provenance information about the query entry.
The index resource itself SHOULD be typed as qvmc:Index
and ldp:RDFSource
and may carry container-level metadata.
Each tq:QueryForm
entry MUST include at least tq:query
, tm:result
, sd:endpoint
, and dct:created
.
The pair (tq:query, tm:result)
MUST be unique within the container.
sd:endpoint
MUST be a valid RDF list of one or more URIs.
dct:created
MUST be in xsd:dateTime.
qvmc:status
MUST be a literal in the range: current
| stale
| failed
.
prov:wasGeneratedBy
MUST include a prov:Activity
with at least prov:used
and prov:modified
.
It is recommended that each tq:QueryForm
SPARQL query entry is identified by an opaque, 10-character token
(e.g., #aBc1d2Ef3g
) composed of integers (0-9) and both lowercase and uppercase letters (a-z, A-Z).
This hash is used as a key to refer to a singular stored SPARQL query entry.
At a minimum, each tq:QueryForm
entry MUST be unique within the queries.ttl
file.
.rq
)
Each SPARQL query entry includes a serialization of the SPARQL algebra for the query, stored in a file named {hash}.rq
.
{hash}
.application/sparql-query
.PREFIX : <https://example.org/ontology/> SELECT ?s ?score WHERE { ?s :score ?score } ORDER BY DESC(?score) LIMIT 10
Each SPARQL query entry includes a serialization of the results for the query, stored in a file named {hash}.*
(where "*" is the descriptive extension of the file-type respresented).
{hash}
.application/sparql-results+json
) or SPARQL Results XML (application/sparql-results+xml
) serialization formats.queries.ttl
@prefix rdfs: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . @prefix prov: <http://www.w3.org/ns/prov#> . @prefix qvmc: <https://vocab.example/qvmc#> . @prefix dc: <http://purl.org/dc/terms/> . @prefix sh: <http://www.w3.org/ns/shacl#> . @prefix tq: <http://www.w3.org/2001/sw/DataAccess/tests/test-query#> . @prefix tm: <http://www.w3.org/2001/sw/DataAccess/tests/test-manifest#> . @prefix sd: <http://www.w3.org/ns/sparql-service-description#> . @prefix se: <https://purl.expasy.org/sparql-examples/ontology#> . @base <https://data.example.org/example/> . <#index> a qvmc:Index ; dc:title "SPARQL Query Materialization Container Example" ; dc:modified "2025-09-25T09:00:00Z"^^xsd:dateTime . <#aBc1d2Ef3g> a tq:QueryForm, tq:QuerySelect, sh:SPARQLExecutable ; dc:title "Top 10 by score" ; dc:description "Returns 10 entities with the highest :score." ; tq:query <aBc1d2Ef3g.rq> ; tm:result <aBc1d2Ef3g.srj> ; sh:select "SELECT ?s ?score WHERE { ?s :score ?score } ORDER BY DESC(?score) LIMIT 10" ; sd:endpoint <#5926e69f-c619-4029-b516-21affc0598e0> ; dc:created "2025-09-24T16:12:03Z"^^xsd:dateTime ; qvmc:status "current" ; prov:wasGeneratedBy [ a prov:Activity ; prov:used <aBc1d2Ef3g.rq>, <#5926e69f-c619-4029-b516-21affc0598e0> ; prov:modified "2025-09-24T16:12:03Z"^^xsd:dateTime ] . <#5926e69f-c619-4029-b516-21affc0598e0> rdfs:first <https://sparql.example.org/sparql/> ; rdfs:rest rdfs:nil .The order in which RDF triples occur in an RDF dataset convey no meaning.
Security and Privacy Note: If access controls are implemented, the following operations are permitted only if authorization is successful:
ldp:BasicContainer
with GET
and POST
/PUT
access rights on all resources for at least one authorized user.GET
and POST
/PUT
methods to other authenticated users and/or the public.
Implementations MUST update queries.ttl
atomically when new members are added, deleted, or modified.
The following describes the requirements for each action:
tq:QueryForm
node with a new unique subject IRI <#${name}>
.
Both results and query serialization files SHOULD be named <#${name}.rq>
and <#${name}.*>
respectively after the <#${name}>
of the tq:QueryForm
node.
Set sd:endpoint
to an RDF list of one or more source URIs that the query targets. Set dc:created
to the creation timestamp.qvmc:status
of the relevant tq:QueryForm
node to stale
.
IMPORTANT if the results of the query change, users SHOULD create a new query entry instead of modifying the existing one to preserve provenance.
In this case, the pre-existing entry's qvmc:status
MUST be set to stale
and the triple qvmc:linkedQuery
<#${updated-entry-name}>
MUST be added.
Whenever a field within an entry is updated, users MUST update prov:wasGeneratedBy
with a new timestamp via dc:modified
.tq:QueryForm
node and all references to its associated files (.rq
, .srj
, .srx
) from queries.ttl
. Optionally, remove the files themselves from the container.PATCH /views/queries.ttl HTTP/1.1 Content-Type: application/sparql-update DELETE { <#aBc1d2Ef3g> dct:modified ?t ; qvmc:status ?s } INSERT { <#aBc1d2Ef3g> dct:modified "2025-09-25T10:01:22Z"^^xsd:dateTime ; qvmc:status "current" } WHERE { OPTIONAL { <#aBc1d2Ef3g> dct:modified ?t ; qvmc:status ?s } }
The index graph MAY include additional metadata such as provenance
(dct:source
), execution timing, result counts, or dataset
snapshots. Unknown properties MUST be ignored by consumers.
A QVMC Server conforms to this specification if it exposes a container satisfying the requirements in
Container model, enforces media types in
File formats, and maintains a valid queries.ttl
as described in
The index.
A QVMC Client conforms if it manipulates members through LDP operations and creates/patches
queries.ttl
entries according to the data model.
queries.ttl
updates with results writes to avoid dangling references.If-Match
) to prevent lost updates.ldp:contains
in RDF representations to help crawlers discover members.