We're removing seat fees and making pricing better for fast-growing teams
Learn moreWhy deploy SF Pulse - TypeScript on Render?
SF Pulse is a TypeScript web application for tracking San Francisco restaurant openings and local events. It uses Astro for server-rendered pages, PostgreSQL for data storage, and supports optional realtime updates via Redis-backed SSE and browser push notifications.
This template pre-configures a complete SF Pulse stack—Astro web service with health checks, PostgreSQL database, Redis for cross-instance SSE fanout, and a cron job that triggers your daily refresh workflow—all wired together through a shared env group so your services can communicate without manual connection string juggling. Instead of separately provisioning a database, setting up Redis, configuring cron schedules, and writing Dockerfiles, you get a production-ready deployment with pre-deploy migrations and proper health checks in one click. Render's managed Postgres and Redis mean no infrastructure maintenance, and the Blueprint pattern lets you version your entire architecture in render.yaml while the env group keeps secrets synchronized across all four services.
Architecture
What you can build
After deploying, you'll have a web app that tracks San Francisco restaurant openings and local events, with data refreshed daily at 7 AM via a scheduled scraping pipeline. The app pulls from sources like Eater SF, SFist, and Michelin, stores everything in PostgreSQL, and optionally pushes realtime updates to connected browsers. You can use it immediately to browse current openings and events, or extend it with push notifications by adding VAPID keys.
Key features
- Astro SSR with Node: Server-renders pages using Astro 6 with the Node adapter, outputting to dist/server/entry.mjs for production deployment.
- Render Workflows integration: Uses @renderinc/sdk to orchestrate a daily scraping pipeline across multiple source scrapers (Eater SF, SFist, Michelin, FunCheap, FAMSF, Cal Academy).
- Redis SSE fanout: Optional Redis pub/sub enables realtime Server-Sent Events broadcast across multiple web service instances.
- LLM-powered parsing: Integrates OpenAI or Anthropic APIs for menu discovery and article parsing, with configurable provider and model selection.
- VAPID push notifications: Supports browser push notifications via web-push with VAPID key authentication for subscription-based updates.
Use cases
- Food blogger tracks new SF restaurant openings with daily automated updates
- Event planner monitors local happenings via realtime push notifications
- Developer deploys multi-service TypeScript app with Render Workflows pipeline
- Neighborhood newsletter curator aggregates Eater SF and FunCheap listings
What's included
Service | Type | Purpose |
|---|---|---|
sf-pulse-realtime | keyvalue | Application service |
sf-pulse | Web Service | Application service |
sf-pulse-daily | Cron Job | Application service |
sf-pulse-db | PostgreSQL | Primary database |
Prerequisites
- LLM API Key: Your OpenAI or Anthropic API key used for menu and article parsing with AI.
- VAPID Public Key: Public web-push key for enabling browser push notifications (generate locally with npx web-push generate-vapid-keys).
- VAPID Private Key: Private web-push key used on the server for sending push notifications (generate locally with npx web-push generate-vapid-keys).
- Render API Key: API key for the Render platform, required by the cron service to trigger the daily workflow.
Next steps
- Open the sf-pulse web service URL and check the homepage — You should see the San Francisco restaurant and events listing page load successfully, though it may be empty until the first data refresh runs
- Trigger the sf-pulse-daily cron job manually from the Dashboard — You should see sf-pulse-workflow logs showing task execution for restaurant and event scraping within a few minutes
- Test the health endpoint by visiting /api/healthz on your web service URL — You should receive a 200 OK response confirming the app is connected to PostgreSQL and running
Resources
Repository
Stack
Tags
For AI agents
Drop into your coding agent to explore and deploy this template.