Data Model

All authoring state — every site, template, page, theme, version, lock, activity entry, publish request and backup record, plus platform-level records — lives in one DynamoDB table, Content_Store. This is a deliberate single-table design: related items share a partition so they can be fetched together with a single Query, and access patterns are served by the composite key plus two GSIs.

Table shape

Content_Store (see components/content-store.json):

  • Primary key: PK (partition, string) + SK (sort, string)
  • GSI1: GSI1PK / GSI1SK
  • GSI2: GSI2PK / GSI2SK
  • Billing: PAY_PER_REQUEST (on-demand)
  • Point-in-time recovery: enabled

On-demand billing means capacity scales automatically with traffic; PITR provides continuous backups at the table level (separate from the application-level backup/restore feature).

Partitioning strategy

Most records for a site share the partition SITE#{siteId}, so a single Query on that partition (optionally filtered with begins_with(SK, …)) returns exactly the slice needed — all templates, all pages, a specific sub-type, etc. Platform-wide records use their own partitions.

Per-site items — PK = SITE#{siteId}

SK pattern
Item
Notes
METADATA
Site record
Display name, domain, settings, theme overrides, robots/AI-crawler flags
THEME
Site theme
Base theme selection + inline theme JSON
BREAKPOINTS
Site breakpoints
Responsive breakpoint overrides
TEMPLATE#{templateId}
Page template
Layout regions and defaults
PAGE#{pageId}
Page
Slug, template ref, hierarchy, zones (component tree), SEO meta, publish status
SITEGROUP#{groupType}
Site access group
Members granted a per-site role
LOCK#{pageId}
Edit lock
Held while a page is being edited
ACTIVITY#{timestamp}#{uuid}
Activity-log entry
Time-ordered audit trail
PUBLISHREQ#{requestId}
Publish request
Draft-approval workflow record
BACKUP#{backupId}
Backup record
Status/step metadata for a site or platform backup

Page versions — PK = SITE#{siteId}#PAGE#{pageId}

SK pattern
Item
VERSION#{versionNumber}
An immutable snapshot of a page, written on each save/publish so history can be listed and restored

Version history lives in its own partition (keyed by site + page) so listing or restoring versions never scans the main site partition.

Platform-wide items

PK
SK
Item
VARIABLE#{name}
METADATA
Design variable (design token) in the Variable Registry
COMPONENT#{componentId}
METADATA
Component definition (metadata for a bundle in Component_Store)
PAGETYPE#{pageTypeId}
METADATA
Page type available when creating templates
PLATFORM
BREAKPOINTS
Platform-default responsive breakpoints

Global secondary indexes

The GSIs serve lookups that don't start from a known PK/SK:

  • GSI1 — domain and slug lookup.
    • Site records project GSI1PK = DOMAIN#{domain} / GSI1SK = METADATA, so an incoming host can be resolved to its site with a single query (used when routing/serving).
    • Pages project GSI1PK = SITE#{siteId} / GSI1SK = SLUG#{slug}, so a page can be found by its slug within a site (e.g. the homepage SLUG#/, the error page SLUG#__error).
    • Component definitions project GSI1PK = COMPONENT so the whole component catalogue can be listed without a table scan.
  • GSI2 — reserved for additional access patterns (declared on the table for forward-compatibility).

Access-pattern examples

Need
Operation
List a site's templates
Query PK = SITE#{siteId} AND begins_with(SK, 'TEMPLATE#')
List a site's pages
Query PK = SITE#{siteId} AND begins_with(SK, 'PAGE#')
Load one page
GetItem PK = SITE#{siteId}, SK = PAGE#{pageId}
Resolve a host to a site
Query GSI1 where GSI1PK = DOMAIN#{host}
Find a page by slug
Query GSI1 where GSI1PK = SITE#{siteId} AND GSI1SK = SLUG#{slug}
List page versions
Query PK = SITE#{siteId}#PAGE#{pageId} AND begins_with(SK, 'VERSION#')
List a site's backups
Query PK = SITE#{siteId} AND begins_with(SK, 'BACKUP#')
List all backups (platform)
Scan filtered by begins_with(SK, 'BACKUP#')
List the component catalogue
Query GSI1 where GSI1PK = COMPONENT

Notes on large items

DynamoDB caps a single item at 400 KB. Bulk data that could exceed this is kept out of individual items:

  • Rendered HTML and site output go to Publish_Store (S3), not DynamoDB.
  • Media/fonts go to Asset_Store (S3).
  • During backups, gathered site content is staged in Backup_Store (S3) rather than accumulated on the backup record, so backups work for sites of any size (see Rendering & publishing).

Continue to API reference »