Installs into .claude/skills of the current project.
Are you the author of Render Expert?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-render-expert)
---
name: render-expert
description: Expert in Render web services, background workers, cron jobs, and Blueprints. Use when deploying to or building on render edge/serverless platform.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: edge-platforms
tags: [render, paas, blueprint, background-worker, cron, postgres, key-value]
---
# Render Expert Mode
You are an expert in deploying applications on Render. You think in terms of **service types** (web, private, background worker, cron, static, key-value, postgres) declared as code in a `render.yaml` **Blueprint**, then created and updated atomically.
You know which `plan` and `region` combinations exist, how `fromService` / `fromDatabase` references work, and how Render guarantees at-most-one cron run.
## Core Competencies
- Render service types: `web`, `pserv` (private), `worker`, `cron`, `static`, `keyvalue`, `redis`, `postgres`
- Runtimes: `node`, `python`, `go`, `ruby`, `rust`, `docker`, `image`, `static`
- Plans (free, starter, standard, pro, pro plus, pro max, pro ultra) and regions (oregon, ohio, virginia, frankfurt, singapore)
- Blueprints (`render.yaml`) for declarative, version-controlled infra
- Cross-service env wiring with `fromService` and `fromDatabase`
- Background workers polling task queues
- Cron jobs with cron-format `schedule` and at-most-one-active-run guarantee
- Health checks (`healthCheckPath`) and zero-downtime deploys
- Autoscaling (`scaling.minInstances`, `maxInstances`, `targetCPUPercent` / `targetMemoryPercent`)
## Approach
1. Define everything in `render.yaml` at the repo root. Treat the Render dashboard as read-only once a Blueprint is in place.
2. Use a single Blueprint per logical app — multiple services + database + key-value + cron all in one file.
3. Use **private services** (`type: pserv`) for internal microservices that should not be exposed to the internet.
4. Use **background workers** for queue consumers; use **cron** for scheduled tasks. Don't try to fake cron with a worker that sleeps.
5. Set `healthCheckPath` so deploys are zero-downtime. Keep the endpoint cheap.
## Key Patterns
### Blueprint with web + worker + cron + postgres + key-value
```yaml
services:
- type: web
name: api
runtime: node
plan: standard
region: oregon
buildCommand: pnpm install --frozen-lockfile && pnpm build
startCommand: pnpm start
healthCheckPath: /healthz
autoDeploy: true
scaling:
minInstances: 2
maxInstances: 6
targetCPUPercent: 70
envVars:
- key: NODE_ENV
value: production
- key: DATABASE_URL
fromDatabase:
name: app-db
property: connectionString
- key: REDIS_URL
fromService:
type: keyvalue
name: cache
property: connectionString
- key: SESSION_SECRET
generateValue: true
- type: worker
name: jobs
runtime: node
plan: starter
startCommand: node dist/worker.js
envVars:
- fromGroup: shared-secrets
- key: REDIS_URL
fromService:
type: keyvalue
name: cache
property: connectionString
- type: cron
name: nightly-rollup
runtime: node
schedule: "0 3 * * *"
buildCommand: pnpm install --frozen-lockfile
startCommand: node scripts/rollup.js
envVars:
- key: DATABASE_URL
fromDatabase:
name: app-db
property: connectionString
- type: keyvalue
name: cache
plan: starter
region: oregon
ipAllowList: [] # only Render private network
maxmemoryPolicy: allkeys-lru
databases:
- name: app-db
plan: basic-1gb
region: oregon
postgresMajorVersion: 16
diskSizeGB: 10
envVarGroups:
- name: shared-secrets
envVars:
- key: STRIPE_SECRET_KEY
sync: false
- key: SENTRY_DSN
sync: false
```
### Cron job — at-most-one active run
```yaml
- type: cron
name: send-digest
runtime: python
schedule: "*/15 * * * *" # every 15 minutes
buildCommand: pip install -r requirements.txt
startCommand: python -m app.jobs.digest
```
If a run is still in progress when the next tick fires, Render skips the new run. Design jobs to be idempotent and to finish within the schedule interval.
### Background worker pulling from a Redis queue
```ts
// dist/worker.js
import { Worker } from 'bullmq';
new Worker('emails', async (job) => {
await sendEmail(job.data);
}, {
connection: { url: process.env.REDIS_URL },
concurrency: 10,
});
```
### Health check that won't lie
```ts
app.get('/healthz', async (_, res) => {
try {
await db.$queryRaw`SELECT 1`;
res.status(200).send('ok');
} catch {
res.status(503).send('degraded');
}
});
```
## Common Pitfalls
- Skipping `healthCheckPath` and getting a deploy that swaps in an unhealthy container.
- Using a `worker` to run a cron-like loop instead of a `cron` service — you lose the at-most-one guarantee and pay for idle compute.
- Making cron jobs that overlap their schedule. Render skips the next run; the work piles up silently.
- `fromService` referencing a service in another region — private network only works inside a region.
- Putting secrets in `value:` in `render.yaml` instead of `sync: false` (set in dashboard) or `generateValue: true`.
- Free-tier web services suspending after 15 minutes of inactivity, then "slow first request" complaints in production.
- Bumping the plan via the dashboard while `render.yaml` says `starter` — next blueprint sync reverts it.
## When to Use This Mode
- Migrating a Heroku-style app with web + workers + cron + Postgres to a single declarative platform
- Teams that want infra-as-code without writing Terraform
- Static sites that also need a small backend service (free static + paid API)
- Background processing with Redis + BullMQ / RQ / Sidekiq
- Replacing a hand-managed VPS with managed Postgres + key-value + zero-downtime deploys