edgepush · self-hostv1.0
agpl-3.0 · run it yourself · no telemetry

your push.
your stack.

Clone the repo. Create a D1, a KV, two queues, a Durable Object. Drop your APNs and FCM credentials in. Two wrangler deploys and you have a push notification service that nobody else can see, throttle, or take down. AGPL-3.0 means you can fork it and keep it forever.

agpl-3.0 server mit sdk + cli zero telemetry no backdoor
├ deploy.sh$ two deploys, ten minutes
# clone + install
git clone https://github.com/akshitkrnagpal/edgepush.git
cd edgepush && pnpm install

# create cloudflare resources
cd apps/api
pnpm wrangler d1 create edgepush
pnpm wrangler kv namespace create edgepush-cache
pnpm wrangler queues create edgepush-dispatch
pnpm wrangler queues create edgepush-dispatch-dlq
pnpm wrangler queues create edgepush-webhook
pnpm wrangler queues create edgepush-webhook-dlq

# paste IDs into wrangler.jsonc, then:
pnpm wrangler secret put ENCRYPTION_KEY
pnpm wrangler secret put BETTER_AUTH_SECRET
pnpm wrangler secret put GITHUB_CLIENT_ID
pnpm wrangler secret put GITHUB_CLIENT_SECRET

# migrate + deploy api
pnpm db:migrate:remote
pnpm deploy

# deploy dashboard
cd ../web && pnpm deploy

# done. send your first push:
edgepush send <token> --title "from my own infra"
─  what you actually get

HOSTED_MODE=false

A single env var that disables every hosted-tier behavior: no plan limits, no quota counter, no Stripe webhook, no retention purge, no operator digest emails. Self-host is a strict superset, not a stripped-down build.

your secret key

ENCRYPTION_KEY is a 32-byte secret you generate with openssl, store in wrangler secrets, and never share. Every APNs .p8 and FCM service account JSON is AES-GCM encrypted under that key before it touches D1.

your D1, your audit log

Every send, every receipt, every credential change writes to your own D1. Operator scripts (replay-dlq, inspect-app) ship in the repo so you can run incident response from your terminal.

active credential probes

The same hourly cron that runs on the hosted tier: probes every stored APNs and FCM credential against Apple and Google, marks them ● ok / ● broken / ● topic mismatch, emails you (if RESEND_API_KEY is set) when something breaks.

real workers infra

D1 + KV + Queues with DLQ + Durable Objects. No external dependencies. No nodejs containers. Cold start is sub-50ms because there is no cold start, it's all native Worker primitives.

MIT sdk + cli

The server is AGPL but @edgepush/sdk and @edgepush/cli are MIT. You can embed the SDK in a closed-source backend or mobile app without copyleft obligations.

─  versions
changelog →

edgepush has no built-in update notifier. Watch the GitHub repo for releases or subscribe to the changelog feed if you want to know when there's something new to pull. Self-host upgrades are a `git pull` + `pnpm install` + `pnpm db:migrate:remote` + pnpm deploy. Additive migrations (new tables, new columns) are safe to apply before deploying; breaking migrations need the deprecate-then-drop pattern.

─  honest tradeoffs

What does AGPL-3.0 mean for me?

If you run edgepush as an internal service inside your company, AGPL is invisible, you don't have to do anything. AGPL only matters if you operate a hosted edgepush AS A SERVICE for third parties (like edgepush.dev does). In that case the AGPL requires you to publish any modifications you make to the server code. SDK + CLI are MIT, so they're unaffected.

Will my self-hosted instance get updates automatically?

No, by design. Self-host means you're in charge. You git pull when you want to upgrade. The hosted tier on edgepush.dev moves at its own pace; your fork moves at yours. The CHANGELOG and the GitHub releases page are how you find out what's new.

Is the self-hosted version a different product than the hosted one?

Same code. The only difference is HOSTED_MODE, false (self-host default) skips the billing and retention paths. Every other feature, including credential probes, dead-letter queue, dashboard, audit log, webhooks, is on by default.

What does it cost to run on Cloudflare?

For most teams, $0. Workers paid plan is $5/mo and unlocks the cron triggers + larger queue burst limits, but you can run on the free tier for trials. D1 + KV + Queues are all in-tier on free or paid. The biggest cost variable is Workers requests above 100K/day, which kicks in at $0.30 per million.

Can I migrate between self-host and the hosted tier?

One direction is easy, the other is manual. Self-host → hosted: sign up at edgepush.dev, re-upload credentials, switch your server's API URL. Hosted → self-host: follow the SELFHOST.md guide and re-upload credentials. There's no automated migration tool because both sides are storing native APNs and FCM tokens, your token list is portable by design.

What if I need help?

Open a GitHub issue. The hosted tier customers get priority email support; self-hosters get the same code, same docs, same SELFHOST.md guide, but support is community-driven through issues.

ready_to_clone

Run edgepush on your infrastructure.

SELFHOST.md walks the full path: prerequisites, resource creation, secrets, migrations, first sign-in, smoke test, troubleshooting. About 20 minutes if you've used Cloudflare Workers before.