An Indore-based logistics firm — 240 staff across a 4-warehouse footprint, a 60-truck fleet, and a 38-person back office — moved off Zoho People after 22 months of patching around its limits. We shipped a custom HRMS in 14 weeks: 8 modules covering attendance, leave, payroll prep, statutory reporting, expense, document management, performance, and a leave-demand-forecasting view the founder asked for after seeing diesel-cost-forecasting in another tool. Here is what we built and the math.
The Answer in 60 Words
We replaced Zoho People Premium with a custom Next.js + PostgreSQL HRMS shipped in 14 weeks. 8 modules. Biometric ZKTeco attendance integration via TCP polling. PF + ESIC + PT statutory reports auto-generated for ESIC portal upload. Leave forecasting using a 3-year rolling baseline.
Why This Matters Now
Indian logistics firms have peculiar HR shapes that off-the-shelf HRMS products do not handle well. The driver workforce works night shifts, sleeps at warehouses, and clocks attendance on biometric devices that do not speak Zoho's API natively. Statutory reporting requires PF (Provident Fund), ESIC (Employees' State Insurance), and state-specific Professional Tax — three different government portals, three different file formats. Zoho People supports the basics but custom statutory exports cost extra and the integration with low-cost biometric devices is unreliable.
Zoho People pricing lists per-user monthly tiers from Essential through People Plus. For 240 users on the Premium plan, that adds up to a large annual bill. Add their Payroll module (an extra per-employee monthly fee for India) and it climbs further. The 22-month patching had cost the firm extra in custom Deluge consulting on top.
The Client (Specific Details)
The 8 Modules (And What Each Does)
The ROI Math (Vs Zoho People)
The board paper had this exact comparison. We did not soften either side; the founder wanted to know "should we build, or should we keep paying Zoho and live with the cracks."
The Year-1 savings number alone does not justify a build. The Year-3 figure (including avoided customisation) is what tipped the founder. The deeper unlock was that the firm now owns the HRMS — they can extend it to add a sales-team field-tracker module in Q2 without paying Zoho's per-user, per-feature ramp.
The Biometric Integration (Where Zoho Failed Hardest)
ZKTeco devices speak a TCP protocol called Standalone. The standard pattern is a poll — your server connects to the device's IP, requests new attendance records, parses the response, stores them. There is no webhook; if the network is flaky the device queues records locally for up to 30 days.
Zoho People relies on a third-party connector for biometric integration. We had four issues with the Zoho approach:
Our solution: a small Node.js poller running on a Hetzner CX22 per warehouse, polling every 60 seconds, with exponential backoff and a local SQLite cache for 30 days. Polls converge to the central API once the network recovers. Total dev time: 2.4 weeks. Total avoided pain: every audit since.
The DIY Walkthrough: Build a Working HRMS Skeleton in 2 Weeks
Below is the trimmed reference build we ship as a starter to firms in the 80-150 employee band. Not the full 240-employee system — the minimum runnable version.
employees, shifts, attendance_punches, leaves, statutory_records. About 14 tables for the core.node-zklib npm package for ZKTeco devices. One worker per device IP, polls every 60s, dedupes by (employee_id, timestamp), forwards new records to the API. Set TCP timeout aggressively (4 seconds) so a flaky network does not block the loop.Common Mistakes (Each One Hurts)
Symptom: "PF audit shows mismatched LOP." Cause: shift-detection logic differs between the HRMS and the manual register. Fix: lock the LOP calculation in writing with the firm's CA before go-live. Run a 30-day parallel period. Reconcile every difference.
Symptom: "Attendance disappears after a power cut." Cause: biometric device lost its records, or the poll missed a window. Fix: configure the device for 30-day local retention. Run the poller in a process supervisor (PM2 or systemd) that auto-restarts. Maintain a per-device watermark of last-seen punch.
Symptom: "The driver is marked absent but he was sleeping at the warehouse." Cause: no punch when sleeping on-site. Fix: special "sleep-on-site" shift code. Warehouse manager marks at end-of-shift via WhatsApp; the system pairs it with the missed-punch.
Symptom: "Leave balance shows negative." Cause: leave-application form did not validate balance at submit. Fix: validate at submit AND at approve (state may have changed in between). Throw a hard error, not a warning.
Symptom: "Year-end appraisal cycle melts the server." Cause: 240 employees + 4 manager-employee combinations + 16 KPIs = 15,360 records loaded in one page. Fix: paginate, lazy-load, and bulk-load into Excel for the actual review session. Do not try to render everything in HTML.
When NOT to Build a Custom HRMS
Skip the build if (a) you are under 80 employees and your processes are still in flux — Zoho People free tier (up to 5 users) or a low-tier Premium plan is fine, (b) your statutory load is light (no PF, no shift workers, urban office only) — KekaHR or Darwinbox handle this well off-the-shelf, or (c) you do not have an internal HR lead who can own the system. A custom HRMS without an internal owner becomes shelf-ware in 9 months.
For a CA-firm comparison case, see our earlier post: Custom HRMS for a 120-Person CA Firm. Different shape — knowledge workers, no shift complexity, no biometric — and the trade-off math came out differently.
Real Outcome (12 Months Post-Launch)
The 14-minute statutory filing number is the one HR loves. Their previous routine was a 4.5-hour Friday-evening grind compiling files from Zoho exports and Excel sheets. Now the file is generated overnight, HR reviews on Friday morning, uploads by 11 am.
A Detail That Saved Us On Day 89
On day 89, our PF ECR generator started outputting a slightly different file format — a missing trailing pipe in the trailer record. EPFO had updated their ECR validator silently. The HR head noticed when the upload bounced. We had a 4-line fix in 22 minutes because we had isolated the format generator behind a single file with a snapshot test of the expected output.
The lesson: statutory file formats are externally controlled. Test the bytes you produce, not just the data you compute.
The Stack Cost Per Month
| Component | Notes |
|---|---|
| Hetzner CCX23 (app + Postgres) | Right-sized for 240 users |
| Hetzner CX22 ×4 (warehouse pollers) | One per warehouse |
| Backup S3 (Cloudflare R2) | 6 GB hot + 7 years archive (compliance) |
| Gupshup WhatsApp | ~3,800 conversations/month |
| MSG91 SMS | Statutory reminders |
| Sentry (errors) | Team plan |
| Engineering retainer (0.4 FTE) | Includes statutory updates |
A Note on Disclosure
The firm asked us to anonymise their name. The numbers in this post are exact; the city and industry are real. We have permission to publish the architecture pattern but not the brand. Standard for our CRM development practice and our HRMS work.
FAQ
What is the actual Zoho People price for India?
Zoho People pricing lists per-user monthly tiers from Essential to People Plus. For India-specific Payroll, an additional fee applies. The exact INR price depends on FX at the time of subscription.
Why not KekaHR or Darwinbox?
We evaluated both. Keka is the strongest off-the-shelf for Indian SMBs and we recommend it for firms with 80-200 standard-shift employees. Darwinbox is enterprise-grade and over-specified for this firm. For a logistics firm with 24/7 shifts, custom statutory edge cases, and a flaky-warehouse-network biometric problem, the build economics tipped to custom.
How did you handle the biometric devices going offline?
Local 30-day buffer on the device + local SQLite cache on the warehouse poller + central reconciliation on the server. We have had two warehouse internet outages of 8+ hours; both auto-reconciled within an hour of network recovery.
Can the firm extend the HRMS themselves?
In year 2, yes. We pair-program with an in-house developer if they hire one. For now they pay our retainer.
What about employee self-service?
Phase 1 included an employee self-service portal: payslip download, leave application, document upload, profile edit. Mobile-friendly PWA — no app install. ~78% of employees use it monthly.
How did you handle the migration from Zoho People?
Zoho's CSV exports for employees, leave balances, attendance history (last 12 months), and document index. Re-imported with deduplication and a 30-day parallel period where both systems received attendance data. Cutover on a Saturday with the HR head onsite.
What was your team composition?
Two full-stack engineers (one senior, one mid), one engineer focused on statutory + biometric integration, Manvi at 0.4 FTE for QA on statutory file formats (this is a high-blast-radius area), and our founder Vivek at 0.2 FTE for client direction. Total: 3.6 FTE for 14 weeks.
Are statutory file formats really that finicky?
Yes. EPFO ECR has 26 fields per row, strict pipe-delimited format, specific date formats, and the validator rejects entire files for a single bad row. Test your generator against the EPFO sample files and run the validator before submission. We caught two format drift issues this way.
Related Reading
If you found this useful
- Custom HRMS for a 120-Person CA Firm — same comparison, different domain
- 400-Person Manufacturer HRMS — bigger scale, different statutory mix
- Our Custom Software Development Service
- For the founder's own perspective on building India SMB software, see Vivek Singh
Need a Custom HRMS Scoping Call?
We ship custom HRMS solutions for Indian SMBs (80-500 employees) in 12-16 weeks, fixed price, with biometric integration, EPFO/ESIC/PT statutory exports, and a leave-forecasting view. First call is technical, with the engineer who would lead your build. Suitable for firms with shift workers or non-standard statutory load.
Book an HRMS Scoping Call
