Proletarian requires MySQL 8.0.1 or later. The minimum version is enforced by Proletarian’s use ofDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/msolli/proletarian/llms.txt
Use this file to discover all available pages before exploring further.
SELECT ... FOR UPDATE SKIP LOCKED, which was added to MySQL in version 8.0.1 and is required for multiple worker threads to dequeue jobs concurrently without contention.
The MySQL schema mirrors the PostgreSQL schema in structure and purpose, but uses MySQL-native types — most notably BINARY(16) for the job ID and TIMESTAMP for time columns. It also requires a different job ID strategy in the Proletarian configuration; see the MySQL UUID strategy section below.
Schema and Table Definitions
The full DDL is reproduced below. Copy this into a migration file or run it directly against your database with the MySQL client.database/mysql/tables.sql
Column Reference
proletarian.job
| Column | Type | Description |
|---|---|---|
job_id | BINARY(16) | Primary key. A UUID stored as 16 raw bytes. Generated and returned by proletarian.job/enqueue! when using the MySQL job ID strategy. |
queue | TEXT | Queue name. Defaults to :proletarian/default when not specified. |
job_type | TEXT | Clojure keyword identifying the job type, e.g. ::send-confirmation-email. |
payload | TEXT | Transit-encoded job data — the map passed as the third argument to enqueue!. |
attempts | INTEGER | Number of processing attempts so far. Starts at 0 and increments each time the job is picked up. |
enqueued_at | TIMESTAMP | Timestamp when the job was first enqueued. Never updated. Stored in UTC. |
process_at | TIMESTAMP | Earliest timestamp at which the job should be executed. Updated on each retry according to the retry strategy’s delay. |
proletarian.archived_job
All columns from proletarian.job are copied verbatim when a job finishes. Two additional columns record the outcome:
| Column | Type | Description |
|---|---|---|
status | TEXT | Either success or failure. Set to failure after all configured retries are exhausted. |
finished_at | TIMESTAMP | Timestamp when the job finished (successfully or after final failure). |
Key Differences from the PostgreSQL Schema
| Aspect | PostgreSQL | MySQL |
|---|---|---|
| Job ID type | UUID (native type) | BINARY(16) (raw bytes) |
| Timestamp type | TIMESTAMPTZ (timezone-aware) | TIMESTAMP (no timezone) |
| Index definition | Separate CREATE INDEX statement | Inline INDEX (queue(256), process_at) inside CREATE TABLE |
| Schema creation | Separate CREATE SCHEMA statement | Inline CREATE DATABASE (MySQL uses databases as schemas) |
Why BINARY(16) for the Job ID?
MySQL does not have a native UUID column type that stores values as compact binary. Using CHAR(36) to store a UUID string wastes space and index performance. Instead, Proletarian stores UUIDs as 16 raw bytes in a BINARY(16) column. This requires a dedicated job ID strategy in the Clojure code — see below.
All timestamps are stored and compared in UTC regardless of the JVM’s default timezone or the MySQL server’s timezone setting. Proletarian always writes
TIMESTAMP values as UTC instants, so your jobs will be processed at the correct wall-clock time even if server or JVM timezones differ.MySQL Job ID Strategy
Proletarian ships theproletarian.job-id-strategies namespace specifically to handle this difference. Require it and pass the MySQL strategy via the :proletarian/job-id-strategy option:
->mysql-uuid-strategy function returns a strategy object that serialises UUIDs to byte[] before writing them to the database and deserialises them back when reading, matching the BINARY(16) storage format.
Installing the Schema
Using the Provided Script
The repository ships a Bash install script atdatabase/mysql/install.sh. It creates the database, the proletarian user, applies tables.sql, and grants the necessary privileges.
Edit the connection variables at the top of the script to match your MySQL server before running it:
database/mysql/db.sql — creates the database:
database/mysql/user.sql — creates the application user:
database/mysql/privileges.sql — grants the minimum required privileges:
Integrating with Migration Tools
If you are already managing schema changes with Flyway or Migratus, copy the contents oftables.sql into a new migration file. No special Proletarian configuration is needed — Proletarian is agnostic about how its tables were created.
Flyway example — create src/main/resources/db/migration/V1__proletarian_tables.sql and paste the contents of tables.sql into it.
Migratus example — create resources/migrations/20240101000000-proletarian-tables.up.sql and paste the SQL there.
Customizing Table and Schema Names
Theproletarian database/schema and table names are fully configurable. Pass the :proletarian/job-table and :proletarian/archived-job-table options to both proletarian.job/enqueue! and proletarian.worker/create-queue-worker using the fully-qualified table name as a string.
The database/schema and table names can be anything you like, but they must be identical in the options passed to
enqueue! and create-queue-worker. If they differ, workers will poll a different table than the one jobs are written to and no jobs will ever be processed.