Netlify is strong at static sites, previews and serverless functions. The alternatives differ in function limits, databases and whether the backend runs in your own cloud account.
Netlify made Git-based deploys, deploy previews and serverless functions the default way to ship a frontend, and it now includes a managed Postgres database with a branch for each deploy preview. Teams look at alternatives when the backend grows beyond functions, for example when jobs run longer than the function limits or the data has to live in the company's own AWS account.
This guide compares the main alternatives, starting with the option that keeps the frontend where it is and moves the backend into your own cloud.
Each option is covered below, starting with Encore.
Encore is infrastructure from code for TypeScript and Go, with a platform that provisions and deploys into your own AWS or GCP account. Services declare their databases, Pub/Sub topics and cron jobs in code, and Encore provisions RDS, SNS and SQS, and Fargate or EKS on AWS, and Encore provisions an IAM role for the service.

In the example below, work that would hit a function time limit moves out of the request: an API call queues an export, a subscriber builds it, and a nightly cron job removes old exports.
// exports/exports.ts
import { api } from "encore.dev/api";
import { CronJob } from "encore.dev/cron";
import { Subscription, Topic } from "encore.dev/pubsub";
import { SQLDatabase } from "encore.dev/storage/sqldb";
const db = new SQLDatabase("exports", { migrations: "./migrations" });
interface ExportRequested {
exportId: number;
accountId: string;
}
export const exportRequested = new Topic<ExportRequested>("export-requested", {
deliveryGuarantee: "at-least-once",
});
// The request returns right away; the export runs in a subscriber.
export const requestExport = api(
{ expose: true, method: "POST", path: "/exports" },
async (req: { accountId: string }): Promise<{ id: number }> => {
const row = await db.queryRow<{ id: number }>`
INSERT INTO exports (account_id) VALUES (${req.accountId}) RETURNING id`;
await exportRequested.publish({ exportId: row!.id, accountId: req.accountId });
return { id: row!.id };
},
);
new Subscription(exportRequested, "build-export", {
handler: async (event) => {
// Build the file here, then mark the export as done.
await db.exec`UPDATE exports SET status = 'done' WHERE id = ${event.exportId}`;
},
});
export const cleanup = api({}, async (): Promise<void> => {
await db.exec`DELETE FROM exports WHERE created_at < NOW() - INTERVAL '30 days'`;
});
new CronJob("cleanup-exports", {
title: "Delete exports older than 30 days",
schedule: "0 3 * * *",
endpoint: cleanup,
});
The migration in exports/migrations creates the exports table the queries use:
-- exports/migrations/1_create_exports.up.sql
CREATE TABLE exports (
id BIGSERIAL PRIMARY KEY,
account_id TEXT NOT NULL,
status TEXT NOT NULL DEFAULT 'pending',
created_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
Run in your terminal to get started locally.
encore run starts Postgres locally along with the Pub/Sub topic, while the cron job only runs in deployed environments. The site can stay on Netlify, since Encore's frontend hosting docs recommend Vercel, Netlify or a similar service for production frontends, and call the backend through a typed client from encore gen client.
When a coding agent adds the export feature, the topic, subscriber and cron schedule it declares are the same objects Encore provisions in the cloud, so reviewing the diff covers the infrastructure change too.
Best fit: teams keeping the frontend on a static host while the backend, its data and its background jobs run in their own AWS or GCP account.
Vercel is the closest like-for-like replacement, with Git deploys, preview URLs and the deepest Next.js support. Its functions default to a 300 second maximum duration, with a 4.5 MB request body limit, according to the Vercel limits docs.
Databases come from Marketplace providers rather than a first-party Postgres, and WebSocket support became generally available in October 2026.
Best fit: Next.js teams that want framework features to land on their host first.
Cloudflare Workers serve static assets and run code on Cloudflare's network, with D1 for SQLite and Hyperdrive for pooled connections to an existing Postgres. CPU time per request is capped, with a 30 second default, and there is no wall-clock limit while the client stays connected, as the Workers limits describe.
Each isolate has 128 MB of memory and code runs in the Workers runtime, so some Node.js libraries need compatibility flags or alternatives.
Best fit: sites that want compute close to users across many regions.
Render hosts static sites next to long-running web services, background workers, cron jobs and managed Postgres, which removes the function time limit entirely for the backend. On the free tier, web services spin down after 15 minutes without traffic and free Postgres databases expire after 30 days.
Best fit: teams that want a static site and an always-on backend on one managed platform.
Amplify Hosting deploys frontends, including server-rendered Next.js, from Git into your AWS account, and Amplify Gen 2 defines the backend in TypeScript. Its data layer is built on AppSync with DynamoDB, and auth uses Cognito.
The backend shape follows Amplify's model of GraphQL over DynamoDB and Lambda functions, which fits CRUD apps better than services with relational data and queues.
Best fit: frontend teams that want hosting and a generated backend inside their own AWS account.
Pick Vercel for Next.js, Cloudflare Workers for edge compute, Render for always-on services on a managed platform, and Amplify for an AWS-native frontend with a generated backend. Pick Encore when the backend needs Postgres, Pub/Sub and cron in your own AWS or GCP account, whichever host serves the frontend.
The same trade-offs appear in our Render vs Vercel comparison and the guide to Vercel alternatives.
Vercel for Next.js, Cloudflare Workers for edge compute with a generous request limit, Render for static sites next to long-running services, and AWS Amplify Hosting for frontends and a TypeScript-defined backend in your AWS account.
Synchronous Netlify Functions run for up to 60 seconds, scheduled functions for 30 seconds, and background functions for up to 15 minutes with a 256 KB payload limit. None of these limits are configurable.
You can keep the site on Netlify and call a backend hosted anywhere over HTTPS, as long as the backend allows the site's origin in its CORS settings and the site reads the API URL from an environment variable per deploy context.
With Encore, publish an event to a Topic from the API handler and do the work in a Subscription handler, so the request returns right away. Scheduled work goes in a CronJob that calls an endpoint on a cron schedule.
Deploy to your cloud on AWS and Google Cloud
without managing infrastructure
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.