Designing Small Apps Around Glitch's Sleep/Wake Container Lifecycle
Glitch's free-tier containers sleep after about five idle minutes, and that one behavior dictates the whole architecture: request-driven code, fast startup, filesystem-or-external state, and secrets confined to .env.
16 Nov 2025, 23:04 UTC

Glitch's free tier puts your project's container to sleep after roughly five minutes without inbound HTTP traffic, and the next request pays a cold-start penalty while the container wakes. That single behavior is the most important engineering constraint on the platform: if you design around it, Glitch is a pleasant home for prototypes, bots, and demos; if you ignore it, you get broken cron jobs, dropped WebSocket connections, and confused users. This note covers the requirements that fit, the smallest design that works, where the trust boundaries sit, and the conditions that should push you to a paid Boosted project or off the platform entirely.
Requirements Glitch actually satisfies
Glitch runs one Node.js container per project, installs dependencies from package.json, and starts your app via its start script. It suits workloads that are request-driven, low-traffic, and tolerant of a slow first response after idle periods. Good fits include webhook receivers, small REST APIs, demo front ends, and teaching projects. Poor fits include anything with scheduled background work, long-lived socket connections, or latency-sensitive first requests.
Before building, confirm the current terms: Glitch's feature set and pricing have shifted over time, including after its acquisition by Fastly, and the sleep behavior described here reflects long-standing free-tier behavior rather than a guaranteed current contract. Check the pricing and help pages before committing a real project to these assumptions.
The smallest suitable design
The minimal architecture has three rules:
- Keep the app request-driven. Every unit of work should be triggered by an inbound HTTP request. Do not rely on
setIntervalor in-process timers for anything that matters, because a sleeping container runs no code at all. - Minimize startup time. Wake latency is the dominant user-visible performance factor. Keep the dependency tree small, defer heavy initialization until first use, and avoid synchronous work at module load. A project that boots in one second feels fine after a nap; one that boots in fifteen seconds feels broken.
- Treat memory as disposable. Anything in process memory vanishes at sleep. Cache for convenience, never for correctness.
A minimal Express app that follows these rules looks like this:
// server.js — run inside the Glitch project container
const express = require("express");
const app = express();
// Lazy, memoized initialization so wake-from-sleep stays fast
let db = null;
function getDb() {
if (!db) {
const Database = require("better-sqlite3");
db = new Database(".data/visits.sqlite");
db.exec("CREATE TABLE IF NOT EXISTS visits (id INTEGER PRIMARY KEY, at TEXT)");
}
return db;
}
app.get("/", (req, res) => {
getDb().prepare("INSERT INTO visits (at) VALUES (?)").run(new Date().toISOString());
const { c } = getDb().prepare("SELECT COUNT(*) AS c FROM visits").get();
res.json({ visits: c });
});
app.listen(process.env.PORT, () => console.log("listening"));Note the database handle is created on first request, not at startup, and the file lives under .data/, a directory Glitch conventionally keeps out of the editor view but on the persistent filesystem.
State and the persistence boundary
The project filesystem persists across restarts and sleep/wake cycles, which makes SQLite or JSON-file storage viable for small, single-instance apps. But persistence is not durability: container rebuilds or platform incidents can lose files. For anything you would be upset to lose, export the data regularly or move it to an external managed database reachable over TLS. The decision rule is simple: one container, low stakes — filesystem is fine; multiple consumers, real users, or money involved — external database.
Verify persistence semantics yourself before relying on them: write a row, trigger a restart from the editor, let the project sleep past the inactivity window, wake it, and read the row back.
Trust boundaries and secrets
Public Glitch projects expose all source code to anyone who views or remixes them — except the .env file, which is excluded from public views and from remixes. That makes .env the only acceptable place for credentials:
# .env — never commit these values anywhere else in the project
API_TOKEN=replace-with-your-token
DATABASE_URL=postgres://user:pass@host:5432/dbnameTwo gaps in that boundary catch people. First, .env protection does not extend to logs or error responses — if your error handler echoes process.env or a stack trace containing a connection string, the secret is public. Second, anything you paste into a tracked file, even temporarily, is visible. You can validate the remix boundary directly: remix a public project that has a .env and confirm the values were not copied.
Operational checks
Three checks confirm the design is behaving as intended:
- Cold-start measurement. Leave the project idle past the inactivity window, then time the first request versus a warm second request (for example,
curl -w "%{time_total}\n" -o /dev/null -s https://your-project.glitch.me/from any machine). The gap tells you the real wake penalty your users see. - Dependency audit. If wake time is high,
npm ls --prodin the project terminal shows what is actually being loaded; trimming here is the highest-leverage fix. - Log review. Check the project log for startup errors that only appear on cold start, such as top-level network calls that time out before the container is fully awake.
Failure modes
The recurring failures on this platform are predictable. Scheduled jobs silently stop because the container sleeps through their window. WebSocket and SSE connections drop at sleep and clients without reconnect logic hang. First requests after idle time out at the caller because the client has a short timeout and the cold start exceeds it. And secrets leak through error pages rather than through source files. Each of these follows from the same root cause, so each has the same fix: move the concern out of the container or make the client tolerant.
A common workaround is an external uptime monitor pinging the app every few minutes to keep it awake. Be aware this may conflict with current acceptable-use terms for free projects — verify before adding one, and treat it as a stopgap rather than an architecture.
When the design changes
Three conditions should change your plan. If you need background workers, cron, or persistent connections, a Boosted (paid) project disables sleeping and makes those viable — that is the intended upgrade path, not a hack. If cold-start latency becomes unacceptable even with a lean app, move to an always-on host. And if the data starts to matter, move storage off the filesystem first, regardless of where the compute runs. The sleep/wake lifecycle is not a flaw to fight; it is the price of free hosting, and the right response is a design that never notices it.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.