package lwt

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

Install

dune-project
 Dependency

Authors

Maintainers

Sources

6.1.0.tar.gz
md5=16d58c8295b5273e58779db0ad1f967a
sha512=d5eafe2f5d2dc576b76db15b84caf69d673cb3d736dc3e40b239e6a42c6036658c78bd4b883e9f2b9f627c144be515b1824f1f2de9d79c05d5744c456fb63257

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

Conflicts

None