macrostack

Layer 5 · self-hosting reality check

What it actually takes to self-host Grist

The docs say Not stated by the vendor. Its docs show one template document served from a container with 100 MB RAM (200 MB with sandboxing) and 1 CPU. In practice you want 8 GB. That is Grist's 'known good configuration for a variety of moderate workloads'. Memory follows how many documents are open at once, because each open document is loaded fully into RAM. Here is the honest version — real requirements, real monthly cost, what you will be maintaining, and the one thing that catches people out.

Usually reached from Airtable alternatives, where Grist is one of the picks.

Wondering whether you need to at all? Is Airtable free? — what the free tier actually allows, and where the wall is.

RAM — documented minimumNot stated by the vendor. Its docs show one template document served from a container with 100 MB RAM (200 MB with sandboxing) and 1 CPU
RAM — what it really needs8 GB. That is Grist's 'known good configuration for a variety of moderate workloads'. Memory follows how many documents are open at once, because each open document is loaded fully into RAM
CPU2 vCPU, the vendor's known-good figure
Disk20 GB is the vendor's known-good figure. Each document is its own SQLite file under /persist/docs. Grist recommends keeping a document under 20 MB of data; past that it slows down or runs into memory limits.
Monthly cost$24–48/mo on an 8 GB VPS. Nothing else is required: documents are SQLite files and the home database defaults to SQLite. Add Redis if you want webhooks and notifications, and S3-compatible storage for automatic snapshots
Setup time15 minutes for one user; an afternoon once you add team sign-in, HTTPS and the sandbox
How you install itdocker run of gristlabs/grist (or gristlabs/grist-oss for purely open-source code) with a volume mounted on /persist. For more than one user, connect OIDC, SAML, forward-auth or 'Sign in with getgrist.com'
Ongoing maintenanceAbout one release a month to pull, a backup of the /persist volume (documents, the home database and sessions), and a sign-in provider to keep working. Low effort once authentication is settled.
Where it stops scalingOne box, sized by the documents open at once rather than by the number of users. Grist staff describe about 30 users on about 10 large documents exhausting a 12 GB box. The multi-server answer is Enterprise-only.

The thing that catches people out

Grist formulas are real Python, and in grist-core they run unsandboxed unless you say otherwise: the gVisor sandbox only starts when GRIST_SANDBOX_FLAVOR=gvisor is set. Without it, anyone who can edit a document can write a formula that reads files on your server. Turning it on can go wrong too. The container refuses to start if the gVisor check fails, which happens on CPUs that hide the XSAVE flag. A Proxmox VM on the default kvm64 CPU type is the classic case, and an open issue reports the same failure on RHEL hosts. Set the variable on day one and confirm the log says 'gvisor check ok'. Then run the docs' test formula glob.glob('/etc/*'), which must come back empty.

When not to self-host Grist

Your tables run to hundreds of thousands of rows, or several heavy documents are open at once. Every open document sits wholly in memory, and the vendor's fix, spreading documents across several servers, is sold only with self-hosted Enterprise. Use Teable or NocoDB on PostgreSQL instead.

Every guide here carries this section. A site that only ever tells you to self-host is selling something — the useful answer is sometimes no.

Other Layer 5 self-hosting guides

Common questions

How much RAM does Grist actually need?
8 GB. That is Grist's 'known good configuration for a variety of moderate workloads'. Memory follows how many documents are open at once, because each open document is loaded fully into RAM in practice. The documented minimum is Not stated by the vendor. Its docs show one template document served from a container with 100 MB RAM (200 MB with sandboxing) and 1 CPU, which is the figure at which the process starts rather than the figure at which it works under real use. 2 vCPU, the vendor's known-good figure alongside it.
What does self-hosting Grist cost per month?
$24–48/mo on an 8 GB VPS. Nothing else is required: documents are SQLite files and the home database defaults to SQLite. Add Redis if you want webhooks and notifications, and S3-compatible storage for automatic snapshots This is commodity VPS pricing and excludes your time, which is the larger cost for most people — budget for about one release a month to pull, a backup of the /persist volume (documents, the home database and sessions), and a sign-in provider to keep working. Low effort once authentication is settled.
How long does it take to set up Grist?
15 minutes for one user; an afternoon once you add team sign-in, HTTPS and the sandbox, via docker run of gristlabs/grist (or gristlabs/grist-oss for purely open-source code) with a volume mounted on /persist. For more than one user, connect OIDC, SAML, forward-auth or 'Sign in with getgrist.com'.
When should I NOT self-host Grist?
Your tables run to hundreds of thousands of rows, or several heavy documents are open at once. Every open document sits wholly in memory, and the vendor's fix, spreading documents across several servers, is sold only with self-hosted Enterprise. Use Teable or NocoDB on PostgreSQL instead.
What is the most common mistake when self-hosting Grist?
Grist formulas are real Python, and in grist-core they run unsandboxed unless you say otherwise: the gVisor sandbox only starts when GRIST_SANDBOX_FLAVOR=gvisor is set. Without it, anyone who can edit a document can write a formula that reads files on your server. Turning it on can go wrong too. The container refuses to start if the gVisor check fails, which happens on CPUs that hide the XSAVE flag. A Proxmox VM on the default kvm64 CPU type is the classic case, and an open issue reports the same failure on RHEL hosts. Set the variable on day one and confirm the log says 'gvisor check ok'. Then run the docs' test formula glob.glob('/etc/*'), which must come back empty.
The Macrostack brief

New swaps, worth your inbox.

A short, occasional email when we add a high-intent alternative or ship a new head-to-head. No spam, no selling your address — unsubscribe in one click.