Skip to main content

Documentation 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.

create-serializer produces the default serializer used by both proletarian.job/enqueue! and proletarian.worker/create-queue-worker. It implements the proletarian.protocols/Serializer protocol using Transit JSON — a format that preserves rich Clojure types (keywords, sets, symbols, etc.) that plain JSON cannot represent. Proletarian’s Transit serializer also ships with built-in read/write handlers for java.time.Instant. Namespace: proletarian.transit

Signature

(create-serializer)
Takes no arguments. Returns a new, stateless Serializer instance on each call.

Return Value

An implementation of proletarian.protocols/Serializer backed by Transit JSON encoding. The returned object is safe to share across threads.

Built-in Type Support

In addition to all standard Transit types (which cover the full Clojure data model), the serializer includes handlers for:
Java typeTransit tagNotes
java.time.Instant"m"Stored as epoch-milliseconds; decoded back to Instant
This means you can include Instant values directly in your job payloads without any additional configuration:
(require '[proletarian.job :as job]
         '[java.time Instant])

(job/enqueue! conn :myapp/schedule-reminder
              {:due-at (Instant/now)
               :message "Don't forget!"})

Basic Usage

(require '[proletarian.transit :as transit]
         '[proletarian.job :as job]
         '[proletarian.worker :as worker])

(def serializer (transit/create-serializer))

;; Enqueueing with the explicit serializer (same as default)
(job/enqueue! conn :myapp/process-report {:report-id 42}
              :proletarian/serializer serializer)

;; Worker using the same serializer instance
(def queue-worker
  (worker/create-queue-worker datasource handle-job
    {:proletarian/serializer serializer}))

Adding Custom Transit Handlers

create-serializer does not accept arguments for additional handlers. If your payloads contain custom types that Transit cannot serialize by default, implement the Serializer protocol directly — merging your handlers with the built-in ones — rather than trying to extend create-serializer. The internal encode/decode functions in proletarian.transit merge any supplied handlers with the default java.time.Instant handlers via clojure.core/merge, so building your own wrapper follows the same pattern:
(require '[cognitect.transit :as transit]
         '[proletarian.protocols :as p])

(defn create-custom-serializer [write-handlers read-handlers]
  (reify p/Serializer
    (encode [_ data]
      (let [out (java.io.ByteArrayOutputStream.)
            writer (transit/writer out :json
                     {:handlers (merge {java.time.Instant
                                        (transit/write-handler
                                          (constantly "m")
                                          #(-> ^java.time.Instant % .toEpochMilli)
                                          #(str (-> ^java.time.Instant % .toEpochMilli)))}
                                       write-handlers)})]
        (transit/write writer data)
        (.toString out "UTF-8")))
    (decode [_ s]
      (let [in (-> s (.getBytes "UTF-8") java.io.ByteArrayInputStream.)
            reader (transit/reader in :json
                     {:handlers (merge {"m" (transit/read-handler
                                              #(java.time.Instant/ofEpochMilli
                                                 (Long/parseLong %)))}
                                       read-handlers)})]
        (transit/read reader)))))

Example: adding a handler for java.time.LocalDate

(require '[cognitect.transit :as transit])

(def write-handlers
  {java.time.LocalDate
   (transit/write-handler (constantly "LocalDate") str)})

(def read-handlers
  {"LocalDate"
   (transit/read-handler java.time.LocalDate/parse)})

(def serializer (create-custom-serializer write-handlers read-handlers))

Source

The full implementation of create-serializer as it appears in proletarian.transit:
(defn create-serializer
  "Create a Transit serializer that implements the proletarian.protocols/Serializer
   protocol. This is the default serializer in Proletarian. It is used in
   proletarian.worker/create-queue-worker and proletarian.job/enqueue!.

   It includes a read and write handler for java.time.Instant. If you need other
   custom handlers, you should implement proletarian.protocols/Serializer with
   your own functions for encoding and decoding."
  []
  (reify p/Serializer
    (encode [_ data] (encode data))
    (decode [_ data-string] (decode data-string))))
If your job payloads contain only standard Clojure data types — maps, vectors, sets, lists, strings, numbers, keywords, symbols, booleans, and nil — the default create-serializer works out of the box with no configuration. You only need a custom serializer when your payload contains host types (Java objects) or third-party types that Transit does not handle natively.
The same serializer must be used when enqueueing and when processing. Proletarian stores payloads as plain text in the database with no serializer metadata, so a worker using a different serializer will fail to decode jobs written by the original serializer. See the Serializer protocol reference for more details.

Build docs developers (and LLMs) love