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

Conflicts

None