HR system scaling
HR system scaling and launch checklist
An HR system stays fast by paginating every list, indexing the main questions, and deferring heavy work until a measured trigger fires. At launch, apply 6 rules, watch 9 signals and hold the performance targets below.
Last checked
Rules to apply at launch
- Pagination: Directory, candidate and audit lists use keyset pagination; page size <= 100; org chart loads one level at a time with lazy expansion.
- Caching: Rule packs and holiday calendars are immutable per version and cached in memory by (id, version); personalised pay data is never cached across users and responses carry no-store.
- Idempotency: Run creation, release, leave approval and application submit use idempotency keys or unique constraints so retries never double-pay, double-accrue or duplicate candidates.
- Rate limits: Public careers and application endpoints are rate limited per IP and per opening with bot protection; payslip downloads and exports are limited per user.
- Data growth: time_entries, audit_log and leave_ledger are partitioned by year or month and archived read-only after retention windows open; payroll records are never dropped within statutory retention.
- Storage: Payslips, resumes and contracts live in a private bucket with per-employee key prefixes and signed short-lived URLs.
Performance targets
| What to measure | Target |
|---|---|
| Employee profile load | p95 < 200 ms including access-log write |
| Payroll calculation for 1,000 employees | < 60 s asynchronous, deterministic result |
| Leave request submit and approve | p95 < 150 ms |
| Payslip PDF render | p95 < 3 s each, batch of 1,000 < 10 min |
What to watch
- Metric payroll run duration and item count: by stage and employer; includes anomaly counts.
- Metric sensitive field reads total: reads of compensation and identity columns by role; spikes indicate snooping.
- Metric pending approvals age: oldest pending leave, timesheet and pay-change approval.
- Log HR audit log: request id, actor, record ids, fields accessed by group; never values.
- Trace payroll run trace: calculate, review, approve, release, payslip render.
- Slo payroll reproducibility: recalculating a released run with its rule pack version yields identical figures; any difference is an incident.
- Slo payslip timeliness: 99% of payslips available by pay date minus one day.
- Alert payroll anomaly blocking: ghost employee, duplicate bank account or variance above threshold blocks release and notifies the payroll lead.
Recurring work
- accrue_leave: runs cron daily. Guard: idempotent per (employee, leave_type, date) through unique (ref_id, reason); uses the leave_accrual rule pack in force.
- calculate_payroll_run: runs queue (jobs) on request. Guard: pure function of inputs and rule pack version; replayable; writes items in one transaction; never touches released runs.
- render_payslips: runs queue (jobs) after approval. Guard: idempotent per item, private bucket, signed URLs, employees notified without amounts in the message.
- remind_pending_approvals: runs cron daily. Guard: one reminder per request per day, capped, escalates to the approver's manager after the window.
- purge_candidate_data: runs cron weekly. Guard: removes rejected candidates after the retention date, keeping anonymised statistics.
- verify_audit_chain: runs cron nightly. Guard: incremental hash chain recompute, break is a sev-1.
Add when the numbers say so
- Read replicas: Headcount analytics and compensation reports run on a read replica when primary CPU > 60% sustained; payroll calculation uses the primary.
Deferred until it is needed
| Deferred | Adopt it when |
|---|---|
| Tax filing and payment integration (payroll provider API) | customer wants filing from the app. |
| E-signature for offers and contracts | offer volume > 20 per month. |
| Benefits carrier connections | benefits enrollment is contracted. |
| Read replica for analytics | primary CPU > 60% sustained. |
On Forge64
Forge64 matches your description to one of 25 reference architectures, writes the plan and data model into the project, generates the app, and runs a quality gate over the code before you see it. Each app gets its own Postgres database and sign-in with no per-user fee. Hosting on Forge Cloud and Forge Payments are rolling out.
Every metered resource on Forge64 has a hard cap, so a traffic spike stops at your limit instead of becoming a surprise bill. This is a reference design for the category, not a promise that every item is generated today. Built-ins such as background jobs, file uploads and search are rolling out; email sent from your app is coming soon, so anything here that needs it is something you add yourself for now.
FAQ
- When should I worry about scale for an HR system?
- Not before a measured trigger fires. For example, for "Tax filing and payment integration (payroll provider API)": customer wants filing from the app.
- What performance targets should an HR system aim for?
- Employee profile load: p95 < 200 ms including access-log write. Payroll calculation for 1,000 employees: < 60 s asynchronous, deterministic result. Leave request submit and approve: p95 < 150 ms.
- Does Forge64 cap my usage costs?
- Yes. Every metered resource has a hard cap, and paid plans add an overage spend cap that you set.
Build your app with Forge64
One prompt to a running app with auth, database, hosting and payments. Start free, no credit card required.
Start building for free