mailZy is a production-grade email job scheduling system designed to handle high-throughput campaigns. It provides granular rate limiting, delayed execution, strict idempotency, and robust crash-recovery mechanisms—all controlled from a sleek Next.js dashboard.
- Distributed Queuing: Powered by BullMQ and Redis for massive scale and reliability.
- Granular Rate Limiting: Atomic Redis Lua scripts enforce global and per-sender hourly limits without race conditions.
- Fault Tolerant: Delayed jobs persist across server restarts. Idempotent job IDs prevent duplicate sends.
- Modern Dashboard: Built with Next.js 14, offering real-time auto-polling queue stats, search, and folder management.
- Per-User Real SMTP Delivery: Connect your own email accounts (Gmail, Outlook, Yahoo, or Custom SMTP) to deliver directly into real recipient inboxes.
- AES-256 Encryption: User SMTP passwords and app passwords are encrypted at rest with AES-256-GCM.
The system is split into two primary components communicating via a REST API:
- Frontend: Next.js 14, Tailwind CSS, Lucide Icons.
- Backend: Express.js, TypeScript, Drizzle ORM.
- Storage & State: PostgreSQL 16 (persistent records), Redis 7 (delayed queues, atomic limits).
- Authentication: Firebase Auth (Google Sign-In).
- Schedule: Campaigns are submitted with a configured
delayBetweenMsandhourlyLimit. - Queue: BullMQ calculates the offset for each recipient and schedules deterministic delayed jobs in Redis.
- Process: Workers pick up matured jobs, evaluating limits via an atomic Lua script.
- Dispatch: Allowed jobs are sent via SMTP; rate-limited jobs are instantly re-queued for the next hourly window.
Follow these steps to get mailZy running locally.
- Node.js 18+
- A PostgreSQL database (e.g. Neon.tech or local PostgreSQL)
- A Redis instance (e.g. local Redis or Redis Cloud)
- A Firebase Project (with Google Sign-In enabled)
Navigate to the backend directory, install dependencies, and configure your environment.
cd backend
cp .env.example .envUpdate .env with your Firebase Admin SDK credentials. Then, initialize the database and start the server:
npm install
npm run db:push # Push the schema to PostgreSQL
npm run dev # Start the backend API on http://localhost:4000Open a new terminal, navigate to the frontend directory, and set up your web environment.
cd frontend
cp .env.example .env.localUpdate .env.local with your Firebase Web client configuration. Then, launch the dashboard:
npm install
npm run dev # Start the Next.js app on http://localhost:3000- Authentication: Open
http://localhost:3000and sign in using Google. - Sender Profiles: Under the Senders tab, connect your Gmail, Outlook, Yahoo, or Custom SMTP mailbox with live connection testing.
- Compose Campaign:
- Click Compose Email.
- Input recipients manually or upload a CSV.
- Use the rich text editor to format your message.
- Set your Delay Between Sends (e.g.,
2s) and Hourly Limit. - Hit Schedule Campaign.
- Live Monitoring: The dashboard automatically polls and updates as emails transition from the delayed queue into the
Sentfolder with real delivery status.
Fine-tune mailZy's behavior via these backend environment variables:
| Variable | Default | Description |
|---|---|---|
WORKER_CONCURRENCY |
5 |
Maximum number of concurrent email workers processing jobs. |
MIN_DELAY_MS |
2000 |
Hard limit for the absolute minimum delay between sends. |
MAX_EMAILS_PER_HOUR |
200 |
Global fallback hourly cap across the entire system. |
MAX_EMAILS_PER_HOUR_PER_SENDER |
100 |
Default per-sender hourly cap (overridable in the UI). |
Built with ❤️ for modern engineering teams.