package lwt

  1. Overview
  2. Docs
Promises and event-driven I/O

Install

dune-project
 Dependency

Authors

Maintainers

Sources

6.1.1.tar.gz
md5=9bccdb35c84cb8097233b3a875f08826
sha512=3c92e3359ee742b9647dc8392b71c2d725b23549327aaab772d48d016d7abb8f0d710d0e9bdc0fd2406e0cbc4ea182cd134446fe4356538795d173cc6a9e0a27

Description

A promise is a value that may become determined in the future.

Lwt provides typed, composable promises. Promises that are resolved by I/O are resolved by Lwt in parallel.

Meanwhile, OCaml code, including code creating and waiting on promises, runs in a single thread by default. This reduces the need for locks or other synchronization primitives. Code can be run in parallel on an opt-in basis.

Published: 24 Feb 2026

README

Lwt

version GitHub Actions status

Lwt is a concurrent programming library for OCaml. It provides a single data type: the promise, which is a value that will become resolved 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) ->
      write outgoing "GET / HTTP/1.1\r\n";%lwt
      write outgoing "Connection: close\r\n\r\n";%lwt
      let%lwt response = read incoming in
      Lwt.return (Some response)))
  in

  let timeout =
    Lwt_unix.sleep 5.;%lwt
    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,lwt_ppx -linkpkg example.ml && ./a.out *)

If you are not using the lwt_ppx syntax extension, you can use the let* binding opoerators from the Lwt.Syntax module instead.

let () =
  let open Lwt.Syntax in
  let request =
    let* 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* () = write outgoing "GET / HTTP/1.1\r\n" in
      let* () = write outgoing "Connection: close\r\n\r\n" in
      let* response = read incoming in
      Lwt.return (Some response)))
  in

  let timeout =
    let* () = 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,lwt_ppx -linkpkg example.ml && ./a.out *)

In the program above, functions such as Lwt_io.write create promises. The let%lwt ... in construct (provided by lwt_ppx) or the let* ... in construct (provided by Lwt.Syntax) are used to wait for a promise to resolve. The code after in is scheduled to run after the code inside the let...in has resolved.

Lwt.pick races 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.


Overview

Lwt compiles to native code on Linux, macOS, Windows, and other systems. It's also routinely compiled to JavaScript for the front end and Node by js_of_ocaml.

In Lwt,

  • The core library Lwt provides promises...
  • ...and a few pure-OCaml helpers, such as promise-friendly mutexes, condition variables, and mvars.
  • There is a big Unix binding, Lwt_unix that binds almost every Unix system call. A higher-level module Lwt_io provides nice I/O channels.
  • Lwt_process is for subprocess handling.
  • Lwt_preemptive spawns system threads.
  • The PPX syntax allows using all of the above without going crazy!
  • There are also some other helpers, such as Lwt_react for reactive programming. See the table of contents on the linked manual pages!

Installing

  1. Use your system package manager to install a development libev package. It is often called libev-dev or libev-devel.
  2. opam install conf-libev lwt

Documentation

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.

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.


Contact

Open an issue, visit Discord chat, ask on discuss.ocaml.org, or on Stack Overflow.

Release announcements are made on discuss.ocaml.org. Watching the repo for "Releases only" is also an option.


Contributing

  • CONTRIBUTING.md contains 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.
  • Ask us anything, whether it's about working on Lwt, or any question at all about it :)
  • The documentation always needs proofreading and fixes.
  • 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!

Libraries to use with Lwt

Dependencies (5)

  1. ocplib-endian
  2. dune-configurator
  3. cppo build & >= "1.1"
  4. ocaml >= "4.14"
  5. dune >= "3.18"

Dev Dependencies (2)

  1. odoc with-doc & >= "2.3"
  2. ocamlfind dev & >= "1.7.3-1"

  1. 0install >= "2.15.1"
  2. aches-lwt
  3. activitypub
  4. albatross
  5. alcotest-lwt
  6. alcotest-mirage
  7. ambient-context-lwt
  8. amqp-client >= "1.1.0"
  9. amqp-client-lwt
  10. angstrom-lwt-unix >= "0.11.0"
  11. anthill
  12. anycache-lwt
  13. archi-lwt
  14. arp
  15. awa-mirage
  16. aws-lwt
  17. aws-s3-lwt < "4.4.0" | >= "4.8.1"
  18. awsm-lwt
  19. azure-cosmos-db
  20. balancer
  21. bastet_lwt
  22. bistro
  23. brisk-reconciler
  24. brozip
  25. builder
  26. builder-web
  27. bun >= "0.3.3"
  28. cachet-lwt
  29. calculon
  30. caldav
  31. camltc
  32. canary
  33. capnp-rpc-lwt < "2.0"
  34. capnp-rpc-unix < "2.1"
  35. caqti-mirage
  36. carton < "1.0.0"
  37. carton-git
  38. carton-lwt
  39. catala-format >= "0.2.0"
  40. cf-lwt
  41. chamelon
  42. chamelon-unix
  43. chamo
  44. charrua-client
  45. charrua-unix
  46. chess_com_api
  47. ciao_lwt
  48. clz
  49. cmdtui-lambda-term
  50. coap
  51. coap-server-lwt
  52. cohttp-curl-lwt
  53. cohttp-lwt
  54. cohttp-lwt-jsoo
  55. cohttp-lwt-unix
  56. cohttp-mirage
  57. cohttp-server-lwt-unix
  58. comby
  59. comby-semantic
  60. conan-lwt
  61. conduit-lwt
  62. conduit-lwt-unix
  63. cowabloga
  64. crunch
  65. cstruct-lwt
  66. csv-lwt
  67. ctypes >= "0.15.0" & < "0.21.1"
  68. ctypes-foreign >= "0.21.1"
  69. curl_lwt
  70. current
  71. current-albatross-deployer
  72. current_docker
  73. current_examples
  74. current_git
  75. current_github
  76. current_gitlab
  77. current_ocluster
  78. current_rpc
  79. current_slack
  80. current_web
  81. dap
  82. data-encoding < "0.1.1"
  83. devkit >= "1.2"
  84. distributed-lwt
  85. dkim-bin < "0.8.0"
  86. dkim-lwt-unix
  87. dkim-mirage
  88. dlm
  89. dmarc
  90. dns-certify
  91. dns-cli
  92. dns-client < "7.0.3"
  93. dns-client-lwt
  94. dns-client-mirage
  95. dns-forward
  96. dns-forward-lwt-unix
  97. dns-lwt
  98. dns-mirage
  99. dns-resolver
  100. dns-server
  101. dns-stub
  102. dnsrobot
  103. dnssd
  104. docker_hub
  105. docteur >= "0.0.2"
  106. docteur-solo5
  107. docteur-unix >= "0.0.5"
  108. doi2bib
  109. dream
  110. dream-httpaf
  111. dream-pure
  112. dream-serve
  113. dropbox
  114. dune >= "3.17.2"
  115. dune-rpc-lwt
  116. earlybird
  117. elasticsearch-cli
  118. emoji = "2.0.0"
  119. equinoxe
  120. ethernet
  121. ez_api >= "1.2.0"
  122. ezcurl-lwt
  123. ezjs_min < "0.2"
  124. ezjsonm-lwt
  125. ezresto
  126. faraday-lwt
  127. faraday-lwt-unix
  128. fat-filesystem
  129. fiber-lwt
  130. fsevents-lwt
  131. fswatch_lwt
  132. gdbprofiler
  133. git
  134. git-cohttp
  135. git-cohttp-unix
  136. git-kv >= "0.2.0"
  137. git-mirage
  138. git-paf
  139. git-unix >= "3.2.0"
  140. github
  141. github-hooks
  142. github-unix >= "4.4.0"
  143. gitlab-unix
  144. gitlab_pipeline_notifier
  145. gluten-lwt
  146. gluten-lwt-unix < "0.4.0"
  147. gluten-mirage < "0.4.0"
  148. graphql-lwt
  149. gremlin
  150. grpc-lwt
  151. guardian
  152. gufo
  153. h1
  154. h1-lwt-unix
  155. h2-lwt
  156. h2-lwt-unix < "0.10.0"
  157. h2-mirage
  158. happy-eyeballs-lwt
  159. happy-eyeballs-mirage
  160. hidapi-lwt
  161. hiredis >= "0.6"
  162. hl_yaml
  163. hockmd
  164. http-lwt-client
  165. http-mirage-client
  166. http-multipart-formdata >= "2.0.0" & < "3.0.0"
  167. httpaf-lwt-unix
  168. httpun-lwt
  169. httpun-mirage
  170. httpun-ws-lwt
  171. hvsock
  172. i3ipc
  173. influxdb-lwt
  174. inotify >= "2.4"
  175. inquire < "0.3.0"
  176. interface-prime-lwt
  177. ip2location
  178. ip2locationio
  179. ip2whois
  180. ipv6-multicast-lwt
  181. irc-client-lwt
  182. irc-client-lwt-ssl
  183. irc-client-tls
  184. irmin
  185. irmin-bench
  186. irmin-chunk
  187. irmin-cli
  188. irmin-client
  189. irmin-containers
  190. irmin-fs
  191. irmin-git
  192. irmin-graphql
  193. irmin-http
  194. irmin-indexeddb
  195. irmin-layers
  196. irmin-mirage-git
  197. irmin-mirage-graphql
  198. irmin-pack
  199. irmin-server
  200. irmin-test
  201. irmin-unix
  202. irmin-watcher
  203. joolog
  204. jose < "0.9.0"
  205. js_of_ocaml-lwt >= "3.5.0"
  206. jsoo_broadcastchannel
  207. jsoo_storage
  208. jupyter
  209. jupyter-kernel
  210. kafka < "0.5"
  211. kafka_lwt
  212. kappa-library
  213. ke >= "0.5"
  214. kinetic-client
  215. kubecaml
  216. lambda-runtime
  217. lambda-term >= "3.3.3"
  218. lambda_streams_lwt
  219. launchd
  220. ldp
  221. learn-ocaml
  222. learn-ocaml-client
  223. ledgerwallet >= "0.4.0"
  224. letsencrypt < "2.0.0"
  225. letsencrypt-app
  226. letsencrypt-dns < "2.0.0"
  227. letters
  228. lichess_api
  229. links >= "0.9.1"
  230. llama
  231. lru_cache
  232. lwt-canceler
  233. lwt-dllist
  234. lwt-exit
  235. lwt-parallel
  236. lwt-pipe
  237. lwt-pipeline
  238. lwt-watcher
  239. lwt_camlp4
  240. lwt_direct >= "6.0.0"
  241. lwt_eio >= "0.6"
  242. lwt_ppx >= "6.0.0"
  243. lwt_react
  244. lwt_retry
  245. lwt_ssl
  246. mariadb >= "1.2.0"
  247. markdown_monolith
  248. markup = "0.7.6"
  249. markup-lwt
  250. mdx
  251. mechaml
  252. mehari-lwt-unix
  253. mehari-mirage
  254. memtrace-mirage
  255. metrics-influx
  256. metrics-lwt
  257. metrics-unix
  258. mimic
  259. mindstorm-lwt
  260. mirage < "4.0.0"
  261. mirage-block >= "2.0.1"
  262. mirage-block-ccm
  263. mirage-block-combinators
  264. mirage-block-lwt
  265. mirage-block-partition
  266. mirage-block-ramdisk
  267. mirage-block-solo5
  268. mirage-block-unikraft
  269. mirage-block-unix >= "2.14.2"
  270. mirage-block-xen
  271. mirage-channel >= "4.0.1"
  272. mirage-channel-lwt
  273. mirage-clock-lwt
  274. mirage-clock-unix < "4.2.0"
  275. mirage-console-lwt
  276. mirage-crypto-rng < "0.11.3"
  277. mirage-crypto-rng-lwt
  278. mirage-crypto-rng-mirage
  279. mirage-device >= "2.0.0"
  280. mirage-flow >= "3.0.0"
  281. mirage-flow-combinators
  282. mirage-flow-lwt
  283. mirage-flow-unix
  284. mirage-fs >= "4.0.0"
  285. mirage-fs-lwt
  286. mirage-kv >= "3.0.1"
  287. mirage-kv-lwt
  288. mirage-kv-unix
  289. mirage-net >= "4.0.0"
  290. mirage-net-lwt
  291. mirage-net-macosx
  292. mirage-net-solo5
  293. mirage-net-unikraft
  294. mirage-net-unix
  295. mirage-net-xen
  296. mirage-profile
  297. mirage-protocols >= "7.0.0"
  298. mirage-protocols-lwt
  299. mirage-qubes
  300. mirage-qubes-ipv4
  301. mirage-runtime
  302. mirage-sleep
  303. mirage-solo5
  304. mirage-stack = "3.0.0"
  305. mirage-stack-lwt
  306. mirage-time >= "3.0.0"
  307. mirage-time-lwt
  308. mirage-time-unix
  309. mirage-types-lwt
  310. mirage-unikraft
  311. mirage-unix
  312. mirage-vnetif
  313. mirage-xen
  314. monorobot
  315. mqtt
  316. mrmime >= "0.5.0"
  317. multipart-form-data
  318. multipart_form >= "0.2.0" & < "0.4.0"
  319. multipart_form-cohttp-lwt < "0.6.0"
  320. multipart_form-lwt
  321. naboris
  322. nbd >= "4.0.3"
  323. nbd-tool
  324. nbd-unix
  325. neo4j_bolt
  326. nottui-lwt
  327. notty-community
  328. nproc
  329. nsq
  330. obuilder
  331. obus >= "1.2.1"
  332. ocluster-api
  333. ocluster-worker
  334. ocplib-resto
  335. ocsigenserver
  336. ocsipersist
  337. ocsipersist-dbm
  338. ocsipersist-lib
  339. ocsipersist-pgsql
  340. ocsipersist-sqlite
  341. oframl
  342. ojs_base
  343. omigrate
  344. oneffs
  345. opam-check-npm-deps >= "4.1.0"
  346. opam-publish >= "3.0.0"
  347. opencage
  348. opentelemetry-client-cohttp-lwt
  349. opentelemetry-client-ocurl-lwt
  350. opentelemetry-cohttp-lwt >= "0.4"
  351. opentelemetry-lwt
  352. opium
  353. opium-graphql
  354. opium_kernel
  355. opomodoro
  356. order-i3-xfce
  357. ordma
  358. oskel >= "0.3.0"
  359. ounit-lwt < "2.2.0"
  360. ounit2-lwt
  361. owork
  362. ozulip
  363. paf
  364. paf-cohttp
  365. passage < "0.1.8"
  366. pcap-format < "0.5.2"
  367. petrol
  368. pgn_parser
  369. pgx_lwt
  370. pgx_lwt_mirage
  371. pgx_lwt_unix < "2.0"
  372. piaf < "0.2.0"
  373. picos_meta
  374. plebeia >= "2.0.0"
  375. plotkicadsch
  376. posix-getopt >= "4.0.2"
  377. ppx_defer >= "0.4.0"
  378. ppx_deriving_rpc
  379. ppx_rapper_lwt
  380. proc-smaps
  381. prof_spacetime
  382. prometheus
  383. prometheus-app
  384. promise_jsoo_lwt
  385. protocol-9p
  386. protocol-9p-unix
  387. proton
  388. pxshot
  389. qcow
  390. qcow-stream
  391. qcow-tool
  392. qcow-types
  393. qdrant < "0.2.0"
  394. qfs >= "0.5"
  395. quests
  396. quickterface
  397. rawlink < "2.1"
  398. rawlink-lwt
  399. rdf_json_ld
  400. rdf_lwt
  401. redis-lwt
  402. reparse-lwt
  403. reparse-lwt-unix
  404. resource-pooling
  405. resp
  406. resp-mirage >= "0.10.0"
  407. resp-unix >= "0.10.0"
  408. resto
  409. resto-cohttp-client = "0.4"
  410. resto-cohttp-server = "0.4"
  411. resto-directory = "0.4"
  412. riak
  413. ringo-lwt
  414. river
  415. rock
  416. rpclib-js
  417. rpclib-lwt
  418. SZXX < "4.0.0"
  419. sanddb
  420. scgi
  421. sendmail-lwt
  422. sendmail-mirage
  423. serial
  424. server-reason-react
  425. session-cohttp-lwt
  426. session-cookie-lwt
  427. session-postgresql-lwt
  428. sessions
  429. shared-block-ring
  430. shared-memory-ring-lwt
  431. sherlodoc
  432. sihl < "0.2.0"
  433. slack
  434. slacko
  435. slipshow
  436. smtml >= "0.7.0"
  437. speed
  438. spin < "0.8.0"
  439. spoke
  440. statocaml
  441. stk
  442. stog
  443. swapfs
  444. syguslib-utils
  445. syndic >= "1.4" & < "1.6.0"
  446. tar-mirage
  447. tar-unix
  448. tcpip
  449. telegraml
  450. terminus
  451. testcontainers
  452. testo-lwt
  453. tidy_email
  454. tls >= "0.10.6" & < "0.16.0"
  455. tls-lwt
  456. tls-mirage
  457. tube
  458. tuntap
  459. twirp_cohttp_lwt_unix
  460. uring
  461. uspf
  462. uspf-lwt
  463. uspf-mirage
  464. utcp
  465. utop
  466. uwt
  467. vchan
  468. vchan-unix
  469. vchan-xen
  470. vercel
  471. vhd-format-lwt
  472. vmnet
  473. vue-jsoo < "0.3"
  474. wayland < "2.0"
  475. webauthn
  476. xen-evtchn
  477. xen-evtchn-unix
  478. xen-gnt
  479. xen-gnt-unix
  480. xenstore
  481. xenstore-tool
  482. xenstore_transport
  483. xlsx2csv
  484. yocaml_git
  485. yocaml_unix < "2.0.0"
  486. zarr-lwt
  487. zmq-lwt >= "5.2.1"

Conflicts

None