Lwt is OCaml's concurrent programming library. It provides a single data type:
the promise, which is a value that will become determined in the future.
Creating a promise spawns a computation. When that computation is I/O, Lwt runs
it in parallel with your OCaml code.
OCaml code, including creating and waiting on promises, is run in a single
thread by default, so you don't have to worry about locking or preemption. You
can detach code to be run in separate threads on an opt-in basis.
Here is a simplistic Lwt program which requests the Google front page, and fails
if the request is not completed in five seconds:
let () = let request = let%lwt addresses = Lwt_unix.getaddrinfo "google.com" "80"  in let google = Lwt_unix.((List.hd addresses).ai_addr) in Lwt_io.(with_connection google (fun (incoming, outgoing) -> let%lwt () = write outgoing "GET / HTTP/1.1\r\n" in let%lwt () = write outgoing "Connection: close\r\n\r\n" in let%lwt response = read incoming in Lwt.return (Some response))) in let timeout = let%lwt () = Lwt_unix.sleep 5. in Lwt.return None in match Lwt_main.run (Lwt.pick [request; timeout]) with | Some response -> print_string response | None -> prerr_endline "Request timed out"; exit 1 (* ocamlfind opt -package lwt.unix -package lwt.ppx -linkpkg -o request example.ml ./request *)
In the program, functions such as
Lwt_io.write create promises. The
let%lwt ... in construct is used to wait for a promise to become determined;
the code after
in is scheduled to run in a "callback."
promises against each other, and behaves as the first one to complete.
Lwt_main.run forces the whole promise-computation network to be executed. All
the visible OCaml code is run in a single thread, but Lwt internally uses a
combination of worker threads and non-blocking file descriptors to resolve in
parallel the promises that do I/O.
Lwt compiles to native code on Linux, macOS, Windows, and other systems. It's
The core library
Lwt_processis for subprocess handling.
Lwt_preemptivespawns system threads.
The PPX syntax allows using all of the above without going crazy!
Use your system package manager to install a development libev package.
It is often called
opam install conf-libev lwt
We are currently working on improving the Lwt documentation (drastically; we are
rewriting the manual). In the meantime:
The current manual can be found here.
Mirage has a nicely-written Lwt tutorial.
An example of a simple server written in Lwt.
Concurrent Programming with Lwt is a nice source of Lwt examples.
They are translations of code from the excellent Real World OCaml, but are
just as useful if you are not reading the book.
Some examples are also available in Lwt's
Note: much of the current manual refers to
'a Lwt.t as "lightweight threads"
or just "threads." This will be fixed in the new manual.
'a Lwt.t is a
promise, and has nothing to do with system or preemptive threads.
Open an issue, visit Gitter chat, ask in #ocaml,
on discuss.ocaml.org, or on Stack Overflow. Please do ask!
Even apparently simple questions often end up educating other users, not to
mention enlightening the maintainers!
Subscribe to the announcements issue to get news about Lwt
releases. It is less noisy than watching the whole repository. Announcements are
also made in /r/ocaml, on the OCaml mailing list, and on
We maintain easy starter issues. These are thoroughly explained
and hyperlinked. We hope that this makes working on Lwt accessible even to
relative OCaml beginners :)
CONTRIBUTING.mdcontains tips for working on the code,
such as how to check the code out, how review works, etc. There is also a
high-level outline of the code base.
The overall development plan can be found in the roadmap.
Ask us anything, whether it's about working on Lwt, or any
question at all about it :)
The documentation always needs proofreading and fixes.
Despite a lot of progress, Lwt still needs more tests.
You are welcome to pick up any other issue, review a PR, add
your opinion, etc.
Any feedback is welcome, including how to make contributing easier!
Lwt is released under the LGPL, with an OpenSSL linking exception. See
>= "1.13" & < "3.3.1"
>= "0.3.0" & < "0.3.3"