Skip to content

Where your data goes

There is no database on this platform, and there will not be one. Nothing a Function writes in one invocation is there in the next.

We decided this on purpose. The data your Function keeps lives in a database you own, in your own account with a provider you choose. We never hold it and we never see the bill.

So a Function that has to remember something needs an account somewhere else first. That is a real cost, and we chose it. In return, your clients’ records stay with you and never with us.

The sandbox has no sockets. Your Function cannot open a TCP connection, bind a UDP port or look up a name. The only way out is an HTTPS request made with fetch.

A database driver that speaks its own wire protocol needs a socket, so it has nothing to connect over. pg, postgres.js, mysql2 and every other driver like them will never work here. The same goes for Redis and MongoDB clients that connect over TCP.

Most of them stop before they run. They import node:net or node:tls, the build has nothing to give them, and wawesome deploy stops at the import.

We will not open sockets later, not even to hosts you allowed. A socket would skip the allowlist, the HTTPS-only rule and the block on private addresses that every outbound call meets.

A database is reached over HTTP, or not at all. Pick a provider that answers queries over HTTPS. Supabase, Turso and Neon all do, and so do many others. Use their HTTP client, not their wire protocol one.

Your App has to allow the database’s host before the first query goes out. Outbound calls says how. Put the address and its key in environment variables, and store the key with --secret.

Each call to your database is its own HTTPS request on a new connection, and nothing keeps one open for the next. These calls count against the outbound call limits on the limits page, and the time each one takes counts against the clock. A database far from your callers adds its round trip to every call, once for each call your handler makes in a row.

The contact-form template does all of this. It serves a form, and each message it gets becomes a row in a Supabase table you own. It writes with one fetch to the table’s HTTPS address, not with a Supabase client library.

You can deploy it before the database exists:

npx wawesome init --template contact-form

Leave the two Supabase values blank when init asks. The page goes live, and a message sent then is answered with a note that there is no database yet. Create the Supabase project and its table after that, then set the address:

npx wawesome env set SUPABASE_URL https://abcd.supabase.co

The template marked SUPABASE_URL as a variable that names a host, so this also adds abcd.supabase.co to the App’s allowlist. Outbound calls says how that works, and what happens if you point the variable at another project later. The template’s page walks through the rest, including why its key is not a secret.