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

Conflicts

None