371 lines
112 KiB
HTML
371 lines
112 KiB
HTML
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta http-equiv="x-ua-compatible" content="ie=edge"/><meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/><meta name="generator" content="Gatsby 5.8.1"/><meta data-react-helmet="true" property="og:image" content="https://images.prismic.io/pusher-website/8f1b29e4-fbb8-45ee-bab8-81d40fe12bbd_Pusher.png?ixlib=gatsbyFP&q=95&auto=compress%2Cformat"/><meta data-react-helmet="true" property="og:type" content="website"/><meta data-react-helmet="true" name="google-site-verification" content="jwI7PUfsfRwYM53d07lRhnl4D1JJfEUrk9JXvtmH180"/><meta data-react-helmet="true" name="facebook-domain-verification" content="qhrday0846mqkzam6n5aq9krqrrlyv"/><meta data-react-helmet="true" property="og:title" content="Low latency, large working set, and GHC’s garbage collector: pick two of three | Pusher blog"/><meta data-react-helmet="true" property="twitter:title" content="Low latency, large working set, and GHC’s garbage collector: pick two of three | Pusher blog"/><meta data-react-helmet="true" name="twitter:site" content="@pusher"/><meta data-react-helmet="true" name="twitter:card" content="summary_large_image"/><meta data-react-helmet="true" name="description" content="Pusher makes it easy for developers to reliably deliver data at scale. A few features we are working on required a rewrite of our internal message bus, but we knew anything we build has to perform as reliably as the existing platform. Our chosen language for this job was Haskell, compiled with GHC. Haskell, unusually \[…\]"/><meta data-react-helmet="true" name="description" property="og:description" content="Pusher makes it easy for developers to reliably deliver data at scale. A few features we are working on required a rewrite of our internal message bus, but we knew anything we build has to perform as reliably as the existing platform. Our chosen language for this job was Haskell, compiled with GHC. Haskell, unusually \[…\]"/><meta data-react-helmet="true" property="twitter:description" content="Pusher makes it easy for developers to reliably deliver data at scale. A few features we are working on required a rewrite of our internal message bus, but we knew anything we build has to perform as reliably as the existing platform. Our chosen language for this job was Haskell, compiled with GHC. Haskell, unusually \[…\]"/><style data-href="/styles.979fd0adeac614b84ee6.css" data-identity="gatsby-global-css">@font-face{font-display:swap;font-family:Maison Neue;font-style:normal;font-weight:500;src:url(/fonts/MaisonNeueWEB-Medium.woff2) format("woff2"),url(/fonts/MaisonNeueWEB-Medium.woff) format("woff")}@font-face{font-display:swap;font-family:Maison Neue;font-style:normal;font-weight:600;src:url(/fonts/MaisonNeueWEB-Demi.woff2) format("woff2"),url(/fonts/MaisonNeueWEB-Demi.woff) format("woff")}@font-face{font-display:swap;font-family:Maison Neue;font-style:normal;font-weight:700;src:url(/fonts/MaisonNeueWEB-Bold.woff2) format("woff2"),url(/fonts/MaisonNeueWEB-Bold.woff) format("woff")}@font-face{font-display:swap;font-family:Maison Neue Mono;font-style:normal;font-weight:400;src:url(/fonts/MaisonNeueMonoWEB-Regular.woff2) format("woff2"),url(/fonts/MaisonNeueMonoWEB-Regular.woff) format("woff")}:root{--rt-color-white:#fff;--rt-color-dark:#222;--rt-color-success:#8dc572;--rt-color-error:#be6464;--rt-color-warning:#f0ad4e;--rt-color-info:#337ab7;--rt-opacity:0.9}.react-tooltip__tooltip_KtSkBq{border-radius:3px;font-size:90%;left:0;opacity:0;padding:8px 16px;pointer-events:none;position:absolute;top:0;transition:opacity .3s ease-out;visibility:hidden;width:-webkit-max-content;width:max-content;will-change:opacity,visibility}.react-tooltip__fixed_KtSkBq{position:fixed}.react-tooltip__arrow_KtSkBq{background:inherit;height:8px;position:absolute;transform:rotate(45deg);width:8px}.react-tooltip__no-arrow_KtSkBq{display:none}.react-tooltip__clickable_KtSkBq{pointer-events:auto}.react-tooltip__show_KtSkBq{opacity:var(--rt-opacity);visibility:visible}.react-tooltip__dark_KtSkBq{background:var(--rt-color-dark);color:var(--rt-color-white)}.react-tooltip__light_KtSkBq{background-color:var(--rt-color-white);color:var(--rt-color-dark)}.react-tooltip__success_KtSkBq{background-color:var(--rt-color-success);color:var(--rt-color-white)}.react-tooltip__warning_KtSkBq{background-color:var(--rt-color-warning);color:var(--rt-color-white)}.react-tooltip__error_KtSkBq{background-color:var(--rt-color-error);color:var(--rt-color-white)}.react-tooltip__info_KtSkBq{background-color:var(--rt-color-info);color:var(--rt-color-white)}[data-rmiz]{position:relative}[data-rmiz-ghost]{pointer-events:none;position:absolute}[data-rmiz-btn-unzoom],[data-rmiz-btn-zoom]{-webkit-appearance:none;appearance:none;background-color:rgba(0,0,0,.7);border:none;border-radius:50%;box-shadow:0 0 1px hsla(0,0%,100%,.5);color:#fff;height:40px;margin:0;outline-offset:2px;padding:9px;touch-action:manipulation;width:40px}[data-rmiz-btn-zoom]:not(:focus):not(:active){clip:rect(0 0 0 0);-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;pointer-events:none;position:absolute;white-space:nowrap;width:1px}[data-rmiz-btn-zoom]{cursor:zoom-in;inset:10px 10px auto auto;position:absolute}[data-rmiz-btn-unzoom]{cursor:zoom-out;inset:20px 20px auto auto;position:absolute;z-index:1}[data-rmiz-content=found] [data-zoom],[data-rmiz-content=found] [role=img],[data-rmiz-content=found] img,[data-rmiz-content=found] svg{cursor:zoom-in}[data-rmiz-modal]::-webkit-backdrop{display:none}[data-rmiz-modal]::backdrop{display:none}[data-rmiz-modal][open]{background:transparent;border:0;height:100vh;height:100svh;margin:0;max-height:none;max-width:none;overflow:hidden;padding:0;position:fixed;width:100vw;width:100svw}[data-rmiz-modal-overlay]{inset:0;position:absolute;transition:background-color .3s}[data-rmiz-modal-overlay=hidden]{background-color:hsla(0,0%,100%,0)}[data-rmiz-modal-overlay=visible]{background-color:#fff}[data-rmiz-modal-content]{height:100%;position:relative;width:100%}[data-rmiz-modal-img]{cursor:zoom-out;image-rendering:high-quality;position:absolute;transform-origin:top left;transition:transform .3s}@media (prefers-reduced-motion:reduce){[data-rmiz-modal-img],[data-rmiz-modal-overlay]{transition-duration:.01ms!important}}</style><title data-react-helmet="true">Low latency, large working set, and GHC’s garbage collector: pick two of three | Pusher blog</title><link data-react-helmet="true" rel="icon" type="image/png" href="/favicon-196x196.png" sizes="196x196"/><link data-react-helmet="true" rel="icon" type="image/png" href="/favicon-128x128.png" sizes="128x128"/><link data-react-helmet="true" rel="icon" type="image/png" href="/favicon-96x96.png" sizes="96x96"/><link data-react-helmet="true" rel="icon" type="image/png" href="/favicon-32x32.png" sizes="32x32"/><link data-react-helmet="true" rel="icon" type="image/png" href="/favicon-16x16.png" sizes="16x16"/><link data-react-helmet="true" rel="preload" href="/fonts/MaisonNeueWEB-Medium.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link data-react-helmet="true" rel="preload" href="/fonts/MaisonNeueWEB-Demi.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link data-react-helmet="true" rel="preload" href="/fonts/MaisonNeueWEB-Bold.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link data-react-helmet="true" rel="preload" href="/fonts/MaisonNeueWEB-BlackItalic.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><link data-react-helmet="true" rel="preload" href="/fonts/MaisonNeueMonoWEB-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous"/><style data-styled="" data-styled-version="5.3.9">.cRTzjR{margin-left:auto;margin-right:auto;padding-left:16px;padding-right:16px;}/*!sc*/
|
||
@media (min-width:700px){.cRTzjR{padding-left:45px;padding-right:45px;}}/*!sc*/
|
||
@media (min-width:1000px){.cRTzjR{max-width:1200px;}}/*!sc*/
|
||
@media (min-width:1400px){.cRTzjR{max-width:1280px;padding-left:85px;padding-right:85px;}}/*!sc*/
|
||
data-styled.g1[id="Container-sc-mqr3kr-0"]{content:"cRTzjR,"}/*!sc*/
|
||
.hZlFEr{font-size:20px;line-height:164%;font-weight:500;-webkit-letter-spacing:0.5px;-moz-letter-spacing:0.5px;-ms-letter-spacing:0.5px;letter-spacing:0.5px;}/*!sc*/
|
||
@media (min-width:1400px){.hZlFEr{font-size:25px;line-height:156%;}}/*!sc*/
|
||
data-styled.g5[id="Text__Heading4-sc-73ytnd-3"]{content:"hZlFEr,"}/*!sc*/
|
||
.bAMNpF{font-weight:500;font-size:16px;line-height:172%;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;font-weight:600;-webkit-letter-spacing:0.5px;-moz-letter-spacing:0.5px;-ms-letter-spacing:0.5px;letter-spacing:0.5px;}/*!sc*/
|
||
.lcqCHo{font-weight:500;font-size:16px;line-height:172%;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;}/*!sc*/
|
||
data-styled.g7[id="Text__Paragraph-sc-73ytnd-5"]{content:"bAMNpF,lcqCHo,"}/*!sc*/
|
||
.jxigDK{font-weight:500;font-size:16px;line-height:28px;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;}/*!sc*/
|
||
data-styled.g8[id="Text__Copyright-sc-73ytnd-6"]{content:"jxigDK,"}/*!sc*/
|
||
.deYSNt{padding:8px 16px;background-color:#8731D2;font-weight:600;font-size:16px;line-height:28px;-webkit-letter-spacing:0.5px;-moz-letter-spacing:0.5px;-ms-letter-spacing:0.5px;letter-spacing:0.5px;color:white;border-radius:4px;-webkit-transition:all 0.1s ease;transition:all 0.1s ease;background-color:#300D4F;border:2px solid #300D4F;}/*!sc*/
|
||
.deYSNt:hover{background-color:#C223CE;}/*!sc*/
|
||
.deYSNt:active{background-color:#DCDCDC;color:#300D4F;}/*!sc*/
|
||
.deYSNt:hover{color:white;background-color:#7d6cad;border:2px solid #7d6cad;}/*!sc*/
|
||
.jvSrRs{padding:8px 16px;background-color:#8731D2;font-weight:600;font-size:16px;line-height:28px;-webkit-letter-spacing:0.5px;-moz-letter-spacing:0.5px;-ms-letter-spacing:0.5px;letter-spacing:0.5px;color:white;border-radius:4px;-webkit-transition:all 0.1s ease;transition:all 0.1s ease;}/*!sc*/
|
||
.jvSrRs:hover{background-color:#C223CE;}/*!sc*/
|
||
.jvSrRs:active{background-color:#DCDCDC;color:#300D4F;}/*!sc*/
|
||
data-styled.g11[id="Buttons__Button-sc-62rjb8-0"]{content:"deYSNt,jvSrRs,"}/*!sc*/
|
||
.dSioBW{z-index:4;}/*!sc*/
|
||
data-styled.g13[id="Navbar__OuterOuterContainer-sc-sxfljo-0"]{content:"dSioBW,"}/*!sc*/
|
||
.kUXEUO{width:100%;background-color:white;z-index:3;}/*!sc*/
|
||
@media (min-width:984px){}/*!sc*/
|
||
data-styled.g14[id="Navbar__OuterContainer-sc-sxfljo-1"]{content:"kUXEUO,"}/*!sc*/
|
||
.erbqUP{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;height:88px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/
|
||
data-styled.g18[id="Navbar__NavbarContent-sc-sxfljo-5"]{content:"erbqUP,"}/*!sc*/
|
||
.xmPtq{max-width:100%;box-shadow:0px 2px 4px rgba(0,0,0,0.07);position:relative;overflow:auto;}/*!sc*/
|
||
@media (min-width:744px){.xmPtq{padding-left:24px;padding-right:24px;}}/*!sc*/
|
||
@media (min-width:984px){.xmPtq{max-width:100%;overflow:initial;}}/*!sc*/
|
||
data-styled.g19[id="Navbar__CustomContainer-sc-sxfljo-6"]{content:"xmPtq,"}/*!sc*/
|
||
.hpflQo{width:120px;height:52px;}/*!sc*/
|
||
data-styled.g20[id="Navbar__Logo-sc-sxfljo-7"]{content:"hpflQo,"}/*!sc*/
|
||
.iGcoOl{display:none;}/*!sc*/
|
||
@media (min-width:984px){.iGcoOl{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-left:30px;}.iGcoOl > li{position:relative;cursor:pointer;}.iGcoOl > li:hover > div{display:block;}.iGcoOl > li:hover > img{-webkit-transform:translateY(0px) rotate(180deg);-ms-transform:translateY(0px) rotate(180deg);transform:translateY(0px) rotate(180deg);}.iGcoOl > li:not(:last-child){margin-right:28px;}.iGcoOl > li > img{margin-left:10px;-webkit-transform:translateY(-2px);-ms-transform:translateY(-2px);transform:translateY(-2px);-webkit-transition:all 0.15s ease-in-out;transition:all 0.15s ease-in-out;}}/*!sc*/
|
||
@media (min-width:1100px){.iGcoOl > li:not(:last-child){margin-right:40px;}}/*!sc*/
|
||
@media (min-width:1248px){.iGcoOl > li:not(:last-child){margin-right:48px;}}/*!sc*/
|
||
data-styled.g24[id="Navbar__CenterMenu-sc-sxfljo-11"]{content:"iGcoOl,"}/*!sc*/
|
||
.hMvIsa{margin-left:auto;}/*!sc*/
|
||
@media (max-width:calc(1000px - 1px)){.hMvIsa a,.hMvIsa button{padding:6px;font-weight:600;line-height:24px;}}/*!sc*/
|
||
@media (min-width:984px){.hMvIsa{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-left:0px;}.hMvIsa li:not(:last-child){margin-right:24px;}}/*!sc*/
|
||
@media (min-width:1248px){.hMvIsa li:not(:last-child){margin-right:32px;}}/*!sc*/
|
||
data-styled.g25[id="Navbar__RightMenu-sc-sxfljo-12"]{content:"hMvIsa,"}/*!sc*/
|
||
.hJfXrn{display:none;}/*!sc*/
|
||
@media (min-width:984px){.hJfXrn{display:block;}}/*!sc*/
|
||
data-styled.g26[id="Navbar__SignIn-sc-sxfljo-13"]{content:"hJfXrn,"}/*!sc*/
|
||
.hIEYyq{width:40px;height:40px;margin-left:16px;cursor:pointer;background-color:#bfb1ff;border-radius:4px;}/*!sc*/
|
||
@media (min-width:984px){.hIEYyq{display:none;}}/*!sc*/
|
||
data-styled.g27[id="Navbar__BurgerMenuContainer-sc-sxfljo-14"]{content:"hIEYyq,"}/*!sc*/
|
||
.ddKFPY{display:block;width:20px;height:2px;background-color:#300D4F;border-radius:10px;-webkit-transform:translate(10px,19px);-ms-transform:translate(10px,19px);transform:translate(10px,19px);-webkit-transition:all 0.3s cubic-bezier(0.455,0.03,0.515,0.955);transition:all 0.3s cubic-bezier(0.455,0.03,0.515,0.955);}/*!sc*/
|
||
.ddKFPY:before{content:'';display:block;width:20px;height:2px;background-color:#300D4F;-webkit-transform:translateY(-7px);-ms-transform:translateY(-7px);transform:translateY(-7px);border-radius:10px;-webkit-transition:all 0.3s cubic-bezier(0.455,0.03,0.515,0.955);transition:all 0.3s cubic-bezier(0.455,0.03,0.515,0.955);}/*!sc*/
|
||
.ddKFPY:after{content:'';display:block;width:20px;height:2px;background-color:#300D4F;-webkit-transform:translateY(5px);-ms-transform:translateY(5px);transform:translateY(5px);border-radius:10px;-webkit-transition:all 0.3s cubic-bezier(0.455,0.03,0.515,0.955);transition:all 0.3s cubic-bezier(0.455,0.03,0.515,0.955);}/*!sc*/
|
||
data-styled.g28[id="Navbar__BurgerMenu-sc-sxfljo-15"]{content:"ddKFPY,"}/*!sc*/
|
||
.hOsrPy{display:none;width:336px;position:absolute;padding-top:8px;left:-122px;}/*!sc*/
|
||
.hOsskx{display:none;width:336px;position:absolute;padding-top:8px;left:-112px;}/*!sc*/
|
||
.hOtdIe{display:none;width:336px;position:absolute;padding-top:8px;left:-133px;}/*!sc*/
|
||
data-styled.g29[id="Navbar__HoverMenu-sc-sxfljo-16"]{content:"hOsrPy,hOsskx,hOtdIe,"}/*!sc*/
|
||
.kMGA-dM{position:relative;padding:8px;background-color:white;box-shadow:0px 1px 16px rgba(0,0,0,0.24);border-radius:6px;z-index:3;}/*!sc*/
|
||
.kMGA-dM a{display:block;}/*!sc*/
|
||
.kMGA-dM a:not(:last-child){margin-bottom:8px;}/*!sc*/
|
||
.kMGA-dM li{padding:16px;border-radius:3px;-webkit-transition:all 0.15s ease-in-out;transition:all 0.15s ease-in-out;}/*!sc*/
|
||
.kMGA-dM li path{-webkit-transition:all 0.15s ease-in-out;transition:all 0.15s ease-in-out;}/*!sc*/
|
||
.kMGA-dM li:hover{background-color:#C223CE;color:white;}/*!sc*/
|
||
.kMGA-dM li:hover path{fill:white;}/*!sc*/
|
||
.kMGA-dM img{padding-bottom:9px;}/*!sc*/
|
||
data-styled.g30[id="Navbar__HoverMenuInner-sc-sxfljo-17"]{content:"kMGA-dM,"}/*!sc*/
|
||
.jZEECk{position:absolute;top:-8px;left:50%;-webkit-transform:translateX(-50%);-ms-transform:translateX(-50%);transform:translateX(-50%);}/*!sc*/
|
||
data-styled.g31[id="Navbar__TriangleTop-sc-sxfljo-18"]{content:"jZEECk,"}/*!sc*/
|
||
.hrGdqM{padding-top:64px;padding-bottom:56px;background-color:#f9f8ff;}/*!sc*/
|
||
@media (min-width:1400px){.hrGdqM{margin-top:60px;}}/*!sc*/
|
||
data-styled.g54[id="Footer__OuterContainer-sc-m2xs96-0"]{content:"hrGdqM,"}/*!sc*/
|
||
.bCGXyl{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}/*!sc*/
|
||
@media (min-width:1000px){.bCGXyl{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;position:relative;}}/*!sc*/
|
||
data-styled.g55[id="Footer__Top-sc-m2xs96-1"]{content:"bCGXyl,"}/*!sc*/
|
||
@media (min-width:1000px){}/*!sc*/
|
||
@media (min-width:1400px){.fnFyoa{position:relative;margin-top:0px;}}/*!sc*/
|
||
data-styled.g56[id="Footer__Bottom-sc-m2xs96-2"]{content:"fnFyoa,"}/*!sc*/
|
||
@media (min-width:1000px){.jlxLIv{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}}/*!sc*/
|
||
data-styled.g57[id="Footer__LogoContainer-sc-m2xs96-3"]{content:"jlxLIv,"}/*!sc*/
|
||
.dqhNYY{width:144px;height:62px;}/*!sc*/
|
||
data-styled.g58[id="Footer__Logo-sc-m2xs96-4"]{content:"dqhNYY,"}/*!sc*/
|
||
.bBLfEl{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;margin-top:24px;margin-bottom:64px;-webkit-column-gap:30px;column-gap:30px;}/*!sc*/
|
||
.bBLfEl li{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin-top:16px;}/*!sc*/
|
||
.bBLfEl a{display:block;}/*!sc*/
|
||
@media (min-width:700px){.bBLfEl{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;margin-top:64px;}}/*!sc*/
|
||
@media (min-width:1000px){.bBLfEl{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;min-width:690px;max-width:690px;margin-top:0px;}}/*!sc*/
|
||
@media (min-width:1400px){.bBLfEl{min-width:720px;max-width:720px;margin-bottom:0px;}}/*!sc*/
|
||
data-styled.g59[id="Footer__Menu-sc-m2xs96-5"]{content:"bBLfEl,"}/*!sc*/
|
||
.jDCSwE{margin-top:40px;}/*!sc*/
|
||
.jDCSwE ul{font-weight:500;}/*!sc*/
|
||
@media (min-width:700px){.jDCSwE{width:calc(100% / 3);margin-top:0px;}}/*!sc*/
|
||
data-styled.g60[id="Footer__SubMenu-sc-m2xs96-6"]{content:"jDCSwE,"}/*!sc*/
|
||
.bLFzET{font-size:16px;line-height:172%;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;font-weight:700;}/*!sc*/
|
||
data-styled.g61[id="Footer__Heading-sc-m2xs96-7"]{content:"bLFzET,"}/*!sc*/
|
||
.chjcen{margin-top:48px;margin-bottom:48px;}/*!sc*/
|
||
.chjcen ul{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:16px 0;}/*!sc*/
|
||
.chjcen li{margin-right:18px;}/*!sc*/
|
||
.chjcen li:last-of-type{margin-right:0;}/*!sc*/
|
||
@media (min-width:1000px){}/*!sc*/
|
||
@media (min-width:1400px){.chjcen{margin-bottom:34px;}}/*!sc*/
|
||
data-styled.g62[id="Footer__SocialMediaContainer-sc-m2xs96-8"]{content:"chjcen,"}/*!sc*/
|
||
.bVuTIP{position:relative;width:100%;}/*!sc*/
|
||
.bVuTIP::before{content:'';background-image:url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTIiIGhlaWdodD0iNyIgdmlld0JveD0iMCAwIDEyIDciIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGQ9Ik0xLjc1NzgxIDEuNDM3NUw2LjAwMDQ1IDUuNjgwMTRMMTAuMjQzMSAxLjQzNzUiIHN0cm9rZT0iIzMwMEQ0RiIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiLz4KPC9zdmc+Cg==);background-size:contain;position:absolute;right:18px;top:18px;width:12px;height:12px;pointer-events:none;background-repeat:no-repeat;}/*!sc*/
|
||
@media (min-width:744px){.bVuTIP{display:none;}}/*!sc*/
|
||
data-styled.g85[id="TableOfContent__MobileWrapper-sc-bf7dii-0"]{content:"bVuTIP,"}/*!sc*/
|
||
.gzMOiX{width:100%;padding:8px 16px;padding-right:32px;border:0px;border-radius:4px;font-size:16px;line-height:24px;font-weight:600;color:#300D4F;-webkit-letter-spacing:0.5px;-moz-letter-spacing:0.5px;-ms-letter-spacing:0.5px;letter-spacing:0.5px;text-overflow:ellipsis;background-color:#e6e2fc;-webkit-appearance:button;-moz-appearance:button;appearance:button;cursor:pointer;outline:none;-webkit-appearance:none;}/*!sc*/
|
||
data-styled.g86[id="TableOfContent__Select-sc-bf7dii-1"]{content:"gzMOiX,"}/*!sc*/
|
||
.fqLCGN{display:none;-webkit-scrollbar-gutter:stable;-moz-scrollbar-gutter:stable;-ms-scrollbar-gutter:stable;scrollbar-gutter:stable;padding-right:4px;overflow-y:hidden;width:100%;max-height:84vh;top:0;}/*!sc*/
|
||
.fqLCGN:hover{overflow-y:auto;}/*!sc*/
|
||
@media (min-width:744px){.fqLCGN{display:block;}}/*!sc*/
|
||
@media (min-width:1248px){.fqLCGN{max-width:264px;}}/*!sc*/
|
||
data-styled.g87[id="TableOfContent__DesktopWrapper-sc-bf7dii-2"]{content:"fqLCGN,"}/*!sc*/
|
||
.jpodUS{display:block;margin-bottom:8px;margin-left:0px;}/*!sc*/
|
||
.jpodUS:first-of-type{border-top:none;}/*!sc*/
|
||
.jpodUS:last-of-type{margin-bottom:0;}/*!sc*/
|
||
data-styled.g88[id="TableOfContent__Heading-sc-bf7dii-3"]{content:"jpodUS,"}/*!sc*/
|
||
.hQgFPV{display:block;background-color:none;font-size:16px;font-weight:600;line-height:24px;padding:4px 8px;border-radius:4px;-webkit-transition:background-color ease 200ms;transition:background-color ease 200ms;}/*!sc*/
|
||
.hQgFPV:hover{opacity:0.7;}/*!sc*/
|
||
data-styled.g89[id="TableOfContent__HeadingLink-sc-bf7dii-4"]{content:"hQgFPV,"}/*!sc*/
|
||
.eLZtaH{color:#4BB543;margin-left:16px;display:none;}/*!sc*/
|
||
data-styled.g90[id="hocs__CopyLinkButton-sc-d5soun-0"]{content:"eLZtaH,"}/*!sc*/
|
||
.fvUeZd{line-height:48px;font-size:36px;font-weight:600;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;}/*!sc*/
|
||
@media (min-width:744px){.fvUeZd{font-size:48px;line-height:64px;}}/*!sc*/
|
||
data-styled.g91[id="Typography__H1-sc-1bnioie-0"]{content:"fvUeZd,"}/*!sc*/
|
||
.jaoFLa{line-height:48px;font-size:32px;font-weight:600;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;}/*!sc*/
|
||
@media (min-width:744px){.jaoFLa{font-size:40px;line-height:52px;}}/*!sc*/
|
||
data-styled.g92[id="Typography__H2-sc-1bnioie-1"]{content:"jaoFLa,"}/*!sc*/
|
||
.kjHJGs{display:inline-block;}/*!sc*/
|
||
@media (min-width:984px){.kjHJGs:hover{-webkit-text-decoration:underline;text-decoration:underline;cursor:pointer;}.kjHJGs:hover .copy{display:inline-block;}}/*!sc*/
|
||
data-styled.g97[id="Typography__H2WithCopyStyling-sc-1bnioie-6"]{content:"kjHJGs,"}/*!sc*/
|
||
.fxSXlu{line-height:28px;font-size:16px;font-weight:600;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;font-weight:500;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;margin:16px 0;}/*!sc*/
|
||
@media (min-width:744px){.fxSXlu{font-size:16px;line-height:28px;}}/*!sc*/
|
||
.fxSXlu:first-of-type{margin-top:0;}/*!sc*/
|
||
.fxSXlu:last-of-type{margin-bottom:0;}/*!sc*/
|
||
data-styled.g101[id="Typography__P-sc-1bnioie-10"]{content:"fxSXlu,"}/*!sc*/
|
||
.eVlkaw{color:#300d4f;border-bottom:2px solid #300d4f;font-weight:600;padding-bottom:1px;-webkit-transition:all 0.15s ease-in;transition:all 0.15s ease-in;}/*!sc*/
|
||
.eVlkaw:hover{cursor:pointer;color:#c223ce;border-color:#c223ce;}/*!sc*/
|
||
data-styled.g102[id="Typography__A-sc-1bnioie-11"]{content:"eVlkaw,"}/*!sc*/
|
||
html{box-sizing:border-box;}/*!sc*/
|
||
*,*::before,*::after{box-sizing:inherit;}/*!sc*/
|
||
:root{-moz-tab-size:4;tab-size:4;}/*!sc*/
|
||
html{line-height:1.15;-webkit-text-size-adjust:100%;}/*!sc*/
|
||
body{margin:0;}/*!sc*/
|
||
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";}/*!sc*/
|
||
hr{height:0;}/*!sc*/
|
||
abbr[title]{-webkit-text-decoration:underline dotted;text-decoration:underline dotted;}/*!sc*/
|
||
b,strong{font-weight:bolder;}/*!sc*/
|
||
code,kbd,samp,pre{font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace;font-size:1em;}/*!sc*/
|
||
small{font-size:80%;}/*!sc*/
|
||
sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline;}/*!sc*/
|
||
sub{bottom:-0.25em;}/*!sc*/
|
||
sup{top:-0.5em;}/*!sc*/
|
||
button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0;}/*!sc*/
|
||
button,select{text-transform:none;}/*!sc*/
|
||
button,[type="button"],[type="reset"],[type="submit"]{-webkit-appearance:button;}/*!sc*/
|
||
button::-moz-focus-inner,[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner{border-style:none;padding:0;}/*!sc*/
|
||
button:-moz-focusring,[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring{outline:1px dotted ButtonText;}/*!sc*/
|
||
fieldset{padding:0.35em 0.75em 0.625em;}/*!sc*/
|
||
legend{padding:0;}/*!sc*/
|
||
progress{vertical-align:baseline;}/*!sc*/
|
||
[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto;}/*!sc*/
|
||
[type="search"]{-webkit-appearance:textfield;outline-offset:-2px;}/*!sc*/
|
||
[type="search"]::-webkit-search-decoration{-webkit-appearance:none;}/*!sc*/
|
||
::-webkit-file-upload-button{-webkit-appearance:button;font:inherit;}/*!sc*/
|
||
summary{display:list-item;}/*!sc*/
|
||
*{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;}/*!sc*/
|
||
body{font-family:'Maison Neue',sans-serif;font-size:16px;line-height:28px;color:#300D4F;}/*!sc*/
|
||
h1,h2,h3,h4,h5,h6{margin:0;}/*!sc*/
|
||
p{margin:0;}/*!sc*/
|
||
ul{list-style:none;padding:0;margin:0;}/*!sc*/
|
||
a{color:inherit;-webkit-text-decoration:none;text-decoration:none;}/*!sc*/
|
||
button{padding:0;margin:0;border:none;background:none;color:inherit;cursor:pointer;}/*!sc*/
|
||
img{vertical-align:middle;}/*!sc*/
|
||
figure{margin:0;}/*!sc*/
|
||
pre{margin:0;}/*!sc*/
|
||
blockquote{margin:0;}/*!sc*/
|
||
.js-focus-visible :focus:not(.focus-visible){outline:none;}/*!sc*/
|
||
input[type='text'],input[type='email']{-webkit-appearance:none;-moz-appearance:none;appearance:none;}/*!sc*/
|
||
textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;}/*!sc*/
|
||
pre,code{font-family:'Maison Neue Mono',sans-serif;}/*!sc*/
|
||
.ReactModal__Content{border:none !important;border-radius:0 !important;}/*!sc*/
|
||
.pagination{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:8px;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;width:100%;margin:0;padding:40px 16px;position:relative;}/*!sc*/
|
||
.pagination .previous,.pagination .next{display:none;}/*!sc*/
|
||
.pagination-li{border-radius:4px;color:#300D4F;}/*!sc*/
|
||
.pagination-li a{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;width:48px;height:48px;cursor:pointer;}/*!sc*/
|
||
.pagination-li:hover,.pagination-li.selected{background-color:#e6e2fc;}/*!sc*/
|
||
.react-tooltip{position:absolute;width:200px !important;background-color:#300D4F !important;padding:8px;border-radius:6px;opacity:1;font-weight:500;font-size:16px;line-height:23px;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;text-align:center;color:white;z-index:9999;}/*!sc*/
|
||
.react-tooltip button{font-weight:600;padding-bottom:1px;border-bottom:3px solid;}/*!sc*/
|
||
.react-tooltip button:hover{color:#300D4F;background-color:white;border-bottom:3px solid white;}/*!sc*/
|
||
.react-tooltip__place-top:after{border-top-color:#300D4F;border-top-width:13px;border-left:13px solid transparent;border-right:13px solid transparent;bottom:-13px;margin-left:-13px;}/*!sc*/
|
||
.react-tooltip__place-left:after{border-left-color:#300D4F;border-left-width:13px;border-top:13px solid transparent;border-bottom:13px solid transparent;right:-13px;margin-top:-13px;}/*!sc*/
|
||
.react-tooltip__place-right:after{border-right-color:#300D4F;border-right-width:13px;border-top:13px solid transparent;border-bottom:13px solid transparent;left:-13px;margin-top:-13px;}/*!sc*/
|
||
.react-tooltip__place-bottom:after{border-bottom-color:#300D4F;border-bottom-width:13px;border-left:13px solid transparent;border-right:13px solid transparent;top:-13px;margin-left:-13px;}/*!sc*/
|
||
.hs-cta-embed{display:none!important;height:0!important;width:100%!important;overflow:hidden!important;}/*!sc*/
|
||
[role='tooltip']{pointer-events:all !important;}/*!sc*/
|
||
data-styled.g573[id="sc-global-jtXiOT1"]{content:"sc-global-jtXiOT1,"}/*!sc*/
|
||
.cWzLmV{background:#C7B9FF;padding:16px 24px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;gap:16px;width:100%;max-height:194px;z-index:2;}/*!sc*/
|
||
@media (min-width:744px){.cWzLmV{min-height:76px;position:-webkit-sticky;position:sticky;top:0px;}}/*!sc*/
|
||
data-styled.g579[id="SearchBar__Container-sc-1rbmdkr-0"]{content:"cWzLmV,"}/*!sc*/
|
||
.dfkKQm{display:block;color:#300d4f;line-height:0;}/*!sc*/
|
||
data-styled.g580[id="SearchBar__BrandLink-sc-1rbmdkr-1"]{content:"dfkKQm,"}/*!sc*/
|
||
.bpeDTq{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:16px;width:100%;}/*!sc*/
|
||
@media (min-width:744px){.bpeDTq{max-width:414px;}}/*!sc*/
|
||
data-styled.g581[id="SearchBar__FormContainer-sc-1rbmdkr-2"]{content:"bpeDTq,"}/*!sc*/
|
||
.dUFhcL{background:transparent;border-style:none;border:2px solid #300d4f;border-radius:4px;color:#300d4f;display:inline-block;-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;font-weight:500;line-height:28px;outline:none;max-height:44px;padding:8px 16px;}/*!sc*/
|
||
.dUFhcL:hover{border-color:#fff;}/*!sc*/
|
||
.dUFhcL:focus{border-color:#fff;}/*!sc*/
|
||
.dUFhcL::-webkit-input-placeholder{color:#300d4f;font-weight:500;}/*!sc*/
|
||
.dUFhcL::-moz-placeholder{color:#300d4f;font-weight:500;}/*!sc*/
|
||
.dUFhcL:-ms-input-placeholder{color:#300d4f;font-weight:500;}/*!sc*/
|
||
.dUFhcL::placeholder{color:#300d4f;font-weight:500;}/*!sc*/
|
||
data-styled.g582[id="SearchBar__Input-sc-1rbmdkr-3"]{content:"dUFhcL,"}/*!sc*/
|
||
.eGOtaE{background:#300d4f;border-radius:4px;color:#fff;font-weight:600;height:44px;}/*!sc*/
|
||
.eGOtaE:hover{background:#fff;color:#300d4f;}/*!sc*/
|
||
@media (max-width:464px){.eGOtaE{width:100%;}}/*!sc*/
|
||
data-styled.g583[id="SearchBar__Submit-sc-1rbmdkr-4"]{content:"eGOtaE,"}/*!sc*/
|
||
.egCjPX{text-transform:capitalize;background-color:#e6e2fc;color:#300d4f;border-radius:4px;padding:4px 8px;font-weight:600;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}/*!sc*/
|
||
data-styled.g584[id="Pill-sc-1gtnmru-0"]{content:"egCjPX,"}/*!sc*/
|
||
@media (min-width:744px){.eiLoiF{display:none;}}/*!sc*/
|
||
data-styled.g676[id="Utils__OnlyOnMobile-sc-btxiab-0"]{content:"eiLoiF,"}/*!sc*/
|
||
.jbxepG{display:none;}/*!sc*/
|
||
@media (min-width:744px){.jbxepG{display:block;}}/*!sc*/
|
||
data-styled.g677[id="Utils__OnlyOnDesktop-sc-btxiab-1"]{content:"jbxepG,"}/*!sc*/
|
||
.gMoEsU{background-color:#231c38;border-radius:8px;font-size:14px;margin:16px 0;overflow:hidden;}/*!sc*/
|
||
.gMoEsU .linenumber{opacity:0.5;}/*!sc*/
|
||
.gMoEsU .codeStyle{background-color:#190c25!important;}/*!sc*/
|
||
data-styled.g740[id="CodeSnippet__CodeBlock-sc-ov4fyy-0"]{content:"gMoEsU,"}/*!sc*/
|
||
.eDNcFJ{background:#F8F6FF;color:#8731D2;padding:0 8px;}/*!sc*/
|
||
data-styled.g741[id="CodeSnippet__Code-sc-ov4fyy-1"]{content:"eDNcFJ,"}/*!sc*/
|
||
.kjuemt{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between;background-color:#231c38;color:#fff;font-family:'Maison Neue';font-weight:600;padding:16px;text-transform:uppercase;width:100%;}/*!sc*/
|
||
data-styled.g742[id="CodeSnippet__Header-sc-ov4fyy-2"]{content:"kjuemt,"}/*!sc*/
|
||
.bIrJuJ{background-color:#190c25!important;height:-12px;-webkit-transition:height 200ms ease;transition:height 200ms ease;}/*!sc*/
|
||
data-styled.g743[id="CodeSnippet__Container-sc-ov4fyy-3"]{content:"bIrJuJ,"}/*!sc*/
|
||
.dkDpiy{background-color:#190c25;color:#fff;padding:16px;position:relative;z-index:0;-webkit-transition:background-color ease 200ms;transition:background-color ease 200ms;}/*!sc*/
|
||
.dkDpiy::after{content:'';display:none;position:absolute;left:0;right:0;top:-50px;bottom:0;background:rgb(0,0,0);background:linear-gradient(0deg,rgba(0,0,0,1) 0%,rgba(0,0,0,0) 100%);z-index:-1;}/*!sc*/
|
||
data-styled.g744[id="CodeSnippet__Footer-sc-ov4fyy-4"]{content:"dkDpiy,"}/*!sc*/
|
||
.iRZIYR{background-color:#fff;color:#231c38;padding:8px 16px;border-radius:4px;font-weight:600;font-family:'Maison Neue';cursor:pointer;}/*!sc*/
|
||
data-styled.g745[id="CodeSnippet__CopyCodeButton-sc-ov4fyy-5"]{content:"iRZIYR,"}/*!sc*/
|
||
.oXmDm{margin:16px auto;padding:8px;}/*!sc*/
|
||
.oXmDm:global [data-rmiz-wrap='visible'],.oXmDm:global [data-rmiz-wrap='hidden']{width:100%;height:100%;display:block;}/*!sc*/
|
||
data-styled.g747[id="ZoomImage__ZoomImageWrapper-sc-agae5n-0"]{content:"oXmDm,"}/*!sc*/
|
||
.QEXmd{display:block;width:100%;max-height:400px;object-fit:contain;}/*!sc*/
|
||
data-styled.g748[id="ZoomImage__CustomImage-sc-agae5n-1"]{content:"QEXmd,"}/*!sc*/
|
||
.bPYiaA h1,.bPYiaA h2,.bPYiaA h3,.bPYiaA h4,.bPYiaA h5{font-weight:600;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;margin:24px 0;-webkit-scroll-margin-top:160px;-moz-scroll-margin-top:160px;-ms-scroll-margin-top:160px;scroll-margin-top:160px;}/*!sc*/
|
||
@media (min-width:744px){.bPYiaA h1,.bPYiaA h2,.bPYiaA h3,.bPYiaA h4,.bPYiaA h5{-webkit-scroll-margin-top:108px;-moz-scroll-margin-top:108px;-ms-scroll-margin-top:108px;scroll-margin-top:108px;}}/*!sc*/
|
||
.bPYiaA .linenumber{opacity:0.5;}/*!sc*/
|
||
data-styled.g749[id="RenderMarkdown__Wrapper-sc-1u2193p-0"]{content:"bPYiaA,"}/*!sc*/
|
||
.fIZfrU{max-width:1200px;margin:0 auto;padding:0 16px;-webkit-scroll-behavior:smooth;-moz-scroll-behavior:smooth;-ms-scroll-behavior:smooth;scroll-behavior:smooth;padding-bottom:32px;}/*!sc*/
|
||
@media (min-width:744px){.fIZfrU{padding:0 24px;padding-bottom:48px;}}/*!sc*/
|
||
@media (min-width:1248px){.fIZfrU{padding:0;padding-bottom:48px;}}/*!sc*/
|
||
data-styled.g764[id="strapiBlogPostSlug__Container-sc-3royxi-0"]{content:"fIZfrU,"}/*!sc*/
|
||
.ewdxkq{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;gap:16px;margin-bottom:32px;padding-bottom:32px;border-bottom:1px solid #eaecf5;}/*!sc*/
|
||
@media (min-width:744px){.ewdxkq{padding-top:0;border-bottom:none;}}/*!sc*/
|
||
data-styled.g765[id="strapiBlogPostSlug__IntroContainer-sc-3royxi-1"]{content:"ewdxkq,"}/*!sc*/
|
||
.iOfIXf{display:unset;padding:24px 0;}/*!sc*/
|
||
@media (min-width:744px){.iOfIXf{border-top:none;border-bottom:none;padding-top:0;max-width:216px;}}/*!sc*/
|
||
@media (min-width:1248px){.iOfIXf{max-width:264px;}}/*!sc*/
|
||
data-styled.g766[id="strapiBlogPostSlug__Info-sc-3royxi-2"]{content:"iOfIXf,"}/*!sc*/
|
||
.ciqtmA{margin:16px 0;}/*!sc*/
|
||
.gbnMkX{margin:16px 0;position:-webkit-sticky;position:sticky;-webkit-align-self:flex-start;-ms-flex-item-align:start;align-self:flex-start;top:32px;}/*!sc*/
|
||
data-styled.g767[id="strapiBlogPostSlug__InfoContent-sc-3royxi-3"]{content:"ciqtmA,gbnMkX,"}/*!sc*/
|
||
.dyACfP{font-weight:600;line-height:16px;margin-bottom:0;}/*!sc*/
|
||
.dyACfP:first-of-type{margin-top:0;}/*!sc*/
|
||
data-styled.g768[id="strapiBlogPostSlug__InfoHeading-sc-3royxi-4"]{content:"dyACfP,"}/*!sc*/
|
||
.RELxG{background-color:#ffffff;top:0;padding:16px 0;left:0;right:0;z-index:2;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}/*!sc*/
|
||
@media (min-width:744px){.RELxG{display:block;z-index:1;padding:0;top:108px;max-width:296px;margin-top:64px;}}/*!sc*/
|
||
data-styled.g769[id="strapiBlogPostSlug__Toc-sc-3royxi-5"]{content:"RELxG,"}/*!sc*/
|
||
.bFWuQN{width:100%;overflow-x:hidden;border-top:1px solid #eaecf5;padding-top:32px;max-width:680px;}/*!sc*/
|
||
@media (min-width:744px){.bFWuQN{padding-top:0;border-top:none;}}/*!sc*/
|
||
.bFWuQN p:first-of-type{margin-top:0;}/*!sc*/
|
||
.bFWuQN img{width:100%;}/*!sc*/
|
||
data-styled.g770[id="strapiBlogPostSlug__Content-sc-3royxi-6"]{content:"bFWuQN,"}/*!sc*/
|
||
.fSgBox{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin:0;}/*!sc*/
|
||
.fSgBox:hover{cursor:pointer;color:#c223ce;border-color:#c223ce;}/*!sc*/
|
||
data-styled.g771[id="strapiBlogPostSlug__Author-sc-3royxi-7"]{content:"fSgBox,"}/*!sc*/
|
||
.bxqSel{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:flex-end;-webkit-box-align:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap;gap:8px;font-size:16px;margin:8px 0;}/*!sc*/
|
||
data-styled.g772[id="strapiBlogPostSlug__ItemTags-sc-3royxi-8"]{content:"bxqSel,"}/*!sc*/
|
||
.gzhCCA{background-color:#300d4f;color:#fff;display:block;padding:8px;border-radius:4px;font-size:16px;font-weight:600;line-height:28px;-webkit-letter-spacing:0.25px;-moz-letter-spacing:0.25px;-ms-letter-spacing:0.25px;letter-spacing:0.25px;-webkit-text-decoration:none;text-decoration:none;}/*!sc*/
|
||
data-styled.g773[id="strapiBlogPostSlug__ShareButton-sc-3royxi-9"]{content:"gzhCCA,"}/*!sc*/
|
||
.cfmUCS{visibility:hidden;height:0;-webkit-scroll-margin-top:156px;-moz-scroll-margin-top:156px;-ms-scroll-margin-top:156px;scroll-margin-top:156px;}/*!sc*/
|
||
data-styled.g774[id="strapiBlogPostSlug__HiddenIntroductionHeading-sc-3royxi-10"]{content:"cfmUCS,"}/*!sc*/
|
||
@media (min-width:744px){.iQxqSG{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:24px;padding-top:64px;}}/*!sc*/
|
||
@media (min-width:984px){.iQxqSG{gap:104px;}}/*!sc*/
|
||
@media (min-width:1248px){.iQxqSG{gap:152px;}}/*!sc*/
|
||
data-styled.g777[id="strapiBlogPostSlug__DesktopView-sc-3royxi-13"]{content:"iQxqSG,"}/*!sc*/
|
||
</style><style>.gatsby-image-wrapper{position:relative;overflow:hidden}.gatsby-image-wrapper picture.object-fit-polyfill{position:static!important}.gatsby-image-wrapper img{bottom:0;height:100%;left:0;margin:0;max-width:none;padding:0;position:absolute;right:0;top:0;width:100%;object-fit:cover}.gatsby-image-wrapper [data-main-image]{opacity:0;transform:translateZ(0);transition:opacity .25s linear;will-change:opacity}.gatsby-image-wrapper-constrained{display:inline-block;vertical-align:top}</style><noscript><style>.gatsby-image-wrapper noscript [data-main-image]{opacity:1!important}.gatsby-image-wrapper [data-placeholder-image]{opacity:0!important}</style></noscript><script type="module">const e="undefined"!=typeof HTMLImageElement&&"loading"in HTMLImageElement.prototype;e&&document.body.addEventListener("load",(function(e){const t=e.target;if(void 0===t.dataset.mainImage)return;if(void 0===t.dataset.gatsbyImageSsr)return;let a=null,n=t;for(;null===a&&n;)void 0!==n.parentNode.dataset.gatsbyImageWrapper&&(a=n.parentNode),n=n.parentNode;const o=a.querySelector("[data-placeholder-image]"),r=new Image;r.src=t.currentSrc,r.decode().catch((()=>{})).then((()=>{t.style.opacity=1,o&&(o.style.opacity=0,o.style.transition="opacity 500ms linear")}))}),!0);</script><link rel="preconnect" href="https://static.cdn.prismic.io"/><link rel="dns-prefetch" href="https://static.cdn.prismic.io"/><link rel="sitemap" type="application/xml" href="/sitemap-index.xml"/></head><body><div id="___gatsby"><div style="outline:none" tabindex="-1" id="gatsby-focus-wrapper"><div class="Navbar__OuterOuterContainer-sc-sxfljo-0 dSioBW"><div class="Navbar__OuterContainer-sc-sxfljo-1 kUXEUO"><div class="Container-sc-mqr3kr-0 Navbar__CustomContainer-sc-sxfljo-6 cRTzjR xmPtq"><div class="Navbar__NavbarContent-sc-sxfljo-5 erbqUP"><a href="/"><img src="/static/pusher-logo-0576fd4af5c38706f96f632235f3124a.svg" alt="Pusher" class="Navbar__Logo-sc-sxfljo-7 hpflQo"/></a><ul class="Navbar__CenterMenu-sc-sxfljo-11 iGcoOl"><li class="Text__Paragraph-sc-73ytnd-5 bAMNpF"><span>Products</span><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiByb2xlPSJpbWciPjxwYXRoIHN0cm9rZT0iIzMwMEQ0RiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0zLjMzMyA2TDggMTEuMzMzIDEyLjY2NyA2Ij48L3BhdGg+PC9zdmc+Cg==" alt=""/><div class="Navbar__HoverMenu-sc-sxfljo-16 hOsrPy"><ul class="Navbar__HoverMenuInner-sc-sxfljo-17 kMGA-dM"><img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDE2IDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNOCAwTDE2IDhIMEw4IDBaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K" alt="" class="Navbar__TriangleTop-sc-sxfljo-18 jZEECk"/><a href="/channels/"><li><svg width="152" height="26" viewBox="0 0 152 26" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M42.3518 4.86432C45.6438 4.86432 48.2014 7.12315 48.5569 10.4016L45.3324 10.9327C44.9976 8.96201 43.931 7.85456 42.3479 7.85456C40.1005 7.85456 38.7666 9.75933 38.7666 12.9486C38.7666 16.1378 40.1005 18.0426 42.3479 18.0426C44.0153 18.0426 45.0833 16.8692 45.3726 14.7202L48.5971 15.2746C48.1975 18.752 45.7502 21.0328 42.3479 21.0328C38.1879 21.0328 35.4707 17.8436 35.4707 12.9486C35.4707 8.05357 38.1918 4.86432 42.3518 4.86432Z" fill="#300D4F"></path><path d="M51.5361 5.19647H54.8281V11.27H59.8771V5.19647H63.1691V20.7034H59.8771V14.2551H54.8281V20.7008H51.5361V5.19647Z" fill="#300D4F"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M69.7069 18.2867H75.668L76.4907 20.7006H79.7606L74.1991 5.19373H71.1744L65.6143 20.7006H68.8842L69.7069 18.2867ZM72.7085 9.69221L74.6653 15.4078H70.7076L72.6644 9.69221H72.7085Z" fill="#300D4F"></path><path d="M82.1826 5.19647H85.5564L90.8311 15.0524H90.8752V5.19647H94.1672V20.7034H90.7895L85.5187 10.8436H85.4746V20.7008H82.1826V5.19647Z" fill="#300D4F"></path><path d="M98.2393 5.19647H101.621L106.892 15.0524H106.936V5.19647H110.228V20.7034H106.847L101.577 10.8436H101.531V20.7008H98.2393V5.19647Z" fill="#300D4F"></path><path d="M114.298 5.19647H124.328V8.20869H117.59V11.354H123.727V14.2331H117.59V17.6886H124.35V20.7008H114.298V5.19647Z" fill="#300D4F"></path><path d="M127.774 5.19647H131.066V17.6886H137.65V20.7008H127.774V5.19647Z" fill="#300D4F"></path><path d="M142.831 14.8974C143.254 17.2015 144.162 18.0918 146.238 18.0918C147.774 18.0918 148.64 17.5375 148.64 16.5631C148.64 15.4776 147.907 14.9465 145.304 14.06C141.679 12.8415 140.323 11.535 140.323 9.25292C140.323 6.66844 142.503 4.86835 145.594 4.86835C148.64 4.86835 151.02 6.70591 151.511 9.43125L148.307 10.1174C147.885 8.54477 147.017 7.81336 145.594 7.81336C144.37 7.81336 143.569 8.36773 143.569 9.23483C143.569 10.0321 144.236 10.4754 146.554 11.2507C148.488 11.9149 149.89 12.6463 150.714 13.4656C151.538 14.2849 151.936 15.3045 151.936 16.567C151.936 19.2471 149.601 21.0407 146.198 21.0407C142.483 21.0407 140.171 19.136 139.614 15.5926L142.831 14.8974Z" fill="#300D4F"></path><path d="M16.4947 1.29257L14.2628 0.0145427C14.2291 -0.00484757 14.1875 -0.00484757 14.1538 0.0145427L11.8947 1.31324C11.861 1.33263 11.8194 1.33263 11.7857 1.31324L9.5266 0.0145427C9.49287 -0.00484757 9.45132 -0.00484757 9.4176 0.0145427L7.18574 1.29257C7.16872 1.30222 7.1582 1.32023 7.1582 1.33974C7.1582 1.35924 7.16872 1.37725 7.18574 1.3869L11.8078 4.05279C11.8248 4.06175 11.8452 4.06175 11.8623 4.05279L16.4895 1.39207C16.5099 1.38452 16.5238 1.36564 16.5249 1.34402C16.526 1.3224 16.5142 1.30218 16.4947 1.29257Z" fill="#6A52FF"></path><path d="M21.2308 4.02081L18.9989 2.73891C18.9652 2.71952 18.9236 2.71952 18.8899 2.73891L11.8946 6.76036C11.8609 6.77975 11.8193 6.77975 11.7856 6.76036L4.79027 2.73891C4.75654 2.71952 4.71499 2.71952 4.68127 2.73891L2.44941 4.02081C2.43239 4.03046 2.42188 4.04847 2.42188 4.06798C2.42188 4.08749 2.43239 4.10549 2.44941 4.11514L11.8076 9.49862C11.8244 9.50888 11.8454 9.50888 11.8621 9.49862L21.2256 4.11514C21.2432 4.10646 21.2547 4.08901 21.2558 4.06948C21.2569 4.04995 21.2473 4.03136 21.2308 4.02081Z" fill="#6A52FF"></path><path d="M14.209 10.9392V13.5055C14.2092 13.5249 14.2196 13.5426 14.2364 13.5522C14.2533 13.5618 14.2739 13.5617 14.2907 13.5521L23.6542 8.1686C23.6711 8.15919 23.6815 8.14137 23.6814 8.12208V5.61901C23.6815 5.58017 23.6608 5.54423 23.6271 5.52476C23.5933 5.50529 23.5517 5.50525 23.5179 5.52467L14.2635 10.8448C14.2297 10.8643 14.2089 10.9003 14.209 10.9392Z" fill="#6A52FF"></path><path d="M14.2907 18.9964L23.6542 13.6129C23.6709 13.6027 23.6812 13.5847 23.6814 13.5651V11.0646C23.6815 11.0258 23.6608 10.9898 23.6271 10.9704C23.5933 10.9509 23.5517 10.9509 23.5179 10.9703L14.2635 16.2917C14.2295 16.311 14.2086 16.3471 14.209 16.3861V18.9512C14.2096 18.9702 14.2202 18.9876 14.237 18.9969C14.2537 19.0061 14.2741 19.0059 14.2907 18.9964Z" fill="#6A52FF"></path><path d="M11.8405 22.9415V12.3012C11.8409 12.2622 11.8201 12.2261 11.786 12.2069L9.63592 10.9702C9.60215 10.9508 9.56052 10.9508 9.52678 10.9703C9.49303 10.9897 9.47231 11.0257 9.47242 11.0645V21.5808C9.47254 21.6196 9.45181 21.6555 9.41807 21.675C9.38432 21.6945 9.3427 21.6945 9.30893 21.6751L7.15882 20.4384C7.12499 20.419 7.1042 20.383 7.10432 20.3441V9.57714C7.10444 9.53824 7.08365 9.50226 7.04982 9.48281L4.89971 8.24743C4.86593 8.22801 4.82431 8.22804 4.79057 8.24751C4.75682 8.26698 4.73609 8.30292 4.73621 8.34176V18.8567C4.73633 18.8956 4.7156 18.9315 4.68186 18.951C4.64811 18.9704 4.60649 18.9705 4.57272 18.9511L2.42261 17.7157C2.38878 17.6962 2.36799 17.6602 2.36811 17.6213V6.84922C2.36822 6.81032 2.34743 6.77434 2.31361 6.75489L0.163497 5.52467C0.129722 5.50525 0.0881023 5.50529 0.0543566 5.52476C0.020611 5.54423 -0.000117278 5.58017 6.92109e-07 5.61901V19.0144C-9.78843e-05 19.0337 0.01034 19.0515 0.0272501 19.0609L11.8081 25.8374C11.8248 25.8477 11.8459 25.8477 11.8626 25.8374L23.6486 19.0609C23.6655 19.0515 23.676 19.0337 23.6759 19.0144V16.5113C23.676 16.4725 23.6553 16.4365 23.6215 16.4171C23.5878 16.3976 23.5461 16.3976 23.5124 16.417L12.004 23.0358C11.9703 23.0552 11.9286 23.0552 11.8949 23.0357C11.8611 23.0163 11.8404 22.9803 11.8405 22.9415Z" fill="#6A52FF"></path></svg><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Build scalable realtime features</p></li></a><a href="/beams/"><li><svg width="107" height="28" viewBox="0 0 107 28" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.6506 5.7014L9.52966 6.9333C9.49647 6.95258 9.47597 6.98816 9.47583 7.02671V25.9249C9.47613 25.944 9.48635 25.9615 9.50275 25.971L11.7313 27.2652C11.7478 27.2748 11.7682 27.2748 11.7848 27.2654C11.8014 27.2559 11.8118 27.2383 11.8121 27.2191V5.79481C11.8119 5.75618 11.7914 5.72056 11.7581 5.7013C11.7248 5.68205 11.6838 5.68209 11.6506 5.7014Z" fill="#2AE9AA"></path><path d="M14.2774 25.7937V23.3745C14.2771 23.3358 14.2973 23.2999 14.3304 23.2804C14.3634 23.2609 14.4043 23.2608 14.4375 23.2802L16.4313 24.4433C16.4638 24.463 16.4838 24.4986 16.4838 24.5369C16.4838 24.5753 16.4638 24.6109 16.4313 24.6306L14.3575 25.8436C14.3405 25.8535 14.3194 25.8532 14.3027 25.8428C14.286 25.8324 14.2763 25.8135 14.2774 25.7937Z" fill="#2AE9AA"></path><path d="M14.1478 20.4191V17.944C14.148 17.9057 14.1689 17.8703 14.2027 17.8512C14.2365 17.8321 14.2781 17.8321 14.3119 17.8513L21.1012 21.7037C21.1354 21.7228 21.1564 21.7585 21.1564 21.7971C21.1564 21.8357 21.1354 21.8713 21.1012 21.8905L18.9206 23.1294C18.9036 23.1387 18.8829 23.1387 18.8659 23.1294L14.1752 20.4675C14.1572 20.458 14.1465 20.4391 14.1478 20.4191Z" fill="#2AE9AA"></path><path d="M14.2774 15.0086V12.5173C14.277 12.4784 14.2977 12.4424 14.3315 12.4228C14.3654 12.4033 14.4072 12.4032 14.4411 12.4226L23.6975 17.719C23.7314 17.7388 23.7522 17.7748 23.7521 17.8137V20.3673C23.7523 20.3867 23.7419 20.4047 23.725 20.4145C23.7081 20.4243 23.6872 20.4243 23.6702 20.4146L14.3047 15.0559C14.2874 15.0464 14.2769 15.0282 14.2774 15.0086Z" fill="#2AE9AA"></path><path d="M14.2773 9.58038V7.08903C14.277 7.0502 14.2977 7.01416 14.3315 6.9946C14.3654 6.97503 14.4072 6.97494 14.4411 6.99436L23.6975 12.2908C23.7314 12.3099 23.7523 12.3456 23.7521 12.3841V14.9391C23.7523 14.9585 23.7419 14.9765 23.725 14.9863C23.7081 14.9961 23.6872 14.9961 23.6702 14.9864L14.3046 9.62501C14.288 9.61616 14.2776 9.59906 14.2773 9.58038Z" fill="#2AE9AA"></path><path d="M6.97893 8.41349L4.85568 9.64537C4.82223 9.66445 4.80161 9.70015 4.80176 9.73878V23.211C4.80206 23.23 4.8123 23.2475 4.82872 23.257L7.05577 24.5511C7.07272 24.5607 7.0934 24.5605 7.11025 24.5508C7.12709 24.5411 7.13763 24.5233 7.138 24.5038V8.50825C7.13705 8.47054 7.11686 8.43596 7.08455 8.41671C7.05224 8.39746 7.01234 8.39625 6.97893 8.41349Z" fill="#2AE9AA"></path><path d="M2.17062 11.1316L0.0539015 12.3627C0.0204852 12.3817 -0.000103667 12.4174 4.09983e-05 12.456V20.4959C-0.000740985 20.5156 0.00971518 20.534 0.0269712 20.5433L2.25545 21.8366C2.27219 21.8463 2.29282 21.8463 2.30952 21.8365C2.32622 21.8267 2.33641 21.8087 2.33624 21.7893V11.2263C2.3366 11.1866 2.31551 11.1497 2.28112 11.1301C2.24674 11.1104 2.20445 11.111 2.17062 11.1316Z" fill="#2AE9AA"></path><path d="M0.0005809 9.37832V6.82351C0.000139741 6.78482 0.0211368 6.74899 0.0552989 6.73014L11.8238 0.0142972C11.8577 -0.00476574 11.8993 -0.00476574 11.9332 0.0142972L23.6976 6.73285C23.7317 6.7517 23.7527 6.78752 23.7523 6.82622V9.37832C23.7525 9.39774 23.7421 9.41577 23.7251 9.42556C23.7082 9.43535 23.6872 9.43539 23.6702 9.42568L11.9058 2.70848C11.8888 2.69908 11.8681 2.69908 11.8511 2.70848L0.0867617 9.42568C0.069594 9.43767 0.0470028 9.43887 0.0286333 9.42878C0.0102637 9.41868 -0.000638621 9.39907 0.0005809 9.37832Z" fill="#2AE9AA"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M35.4341 6.5199H41.8652C44.426 6.5199 46.2665 8.1847 46.2665 10.4816C46.2665 11.6823 45.6954 12.6789 44.7648 13.2411V13.2838C46.0341 13.8732 46.8168 15.1386 46.8168 16.6767C46.8168 19.7788 44.9763 21.2691 41.189 21.2691H35.4341V6.5199ZM41.4223 12.3969C42.5437 12.3969 43.1576 11.8489 43.1576 10.8381C43.1576 9.848 42.5437 9.29996 41.4223 9.29996H38.5669V12.4021L41.4223 12.3969ZM43.7077 16.6532C43.7077 17.8967 43.0938 18.4861 41.7608 18.4861L38.5654 18.4822V14.8631H41.7816C43.0302 14.8631 43.7077 15.4899 43.7077 16.6532Z" fill="#300D4F"></path><path d="M49.8616 6.51831H59.4051V9.38389H52.9934V12.3761H58.834V15.115H52.9934V18.4097H59.4259V21.2753H49.8616V6.51831Z" fill="#300D4F"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M65.0104 18.972H70.681L71.4585 21.2676H74.5735L69.2845 6.51831H66.407L61.1167 21.2689H64.2317L65.0104 18.972ZM67.8649 10.7967L69.7274 16.2332H65.9608L67.8233 10.7967H67.8649Z" fill="#300D4F"></path><path d="M76.8792 6.51831H80.3485L84.5018 16.4425H84.5433L88.707 6.51831H92.1763V21.2689H89.1081V12.1667H89.0666L85.1949 21.2689H83.8399L79.9889 12.1667H79.9474V21.2689H76.8792V6.51831Z" fill="#300D4F"></path><path d="M98.0578 15.7484C98.4602 17.9457 99.3272 18.7833 101.295 18.7833C102.755 18.7833 103.58 18.2559 103.58 17.3292C103.58 16.2951 102.882 15.791 100.406 14.9483C96.9572 13.785 95.6671 12.5455 95.6671 10.3753C95.6671 7.91039 97.7437 6.20422 100.681 6.20422C103.58 6.20422 105.844 7.95304 106.31 10.5446L103.262 11.1909C102.86 9.69539 102.036 9 100.681 9C99.5128 9 98.7561 9.52607 98.7561 10.3481C98.7561 11.1069 99.3908 11.5282 101.591 12.2663C103.431 12.8983 104.764 13.5924 105.548 14.3731C106.332 15.1538 106.716 16.1219 106.716 17.3227C106.716 19.8716 104.494 21.5791 101.257 21.5791C97.7243 21.5791 95.5243 19.7695 94.9948 16.396L98.0578 15.7484Z" fill="#300D4F"></path></svg><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Programmatic push notifications</p></li></a></ul></div></li><li class="Text__Paragraph-sc-73ytnd-5 bAMNpF"><span>Developers</span><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiByb2xlPSJpbWciPjxwYXRoIHN0cm9rZT0iIzMwMEQ0RiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0zLjMzMyA2TDggMTEuMzMzIDEyLjY2NyA2Ij48L3BhdGg+PC9zdmc+Cg==" alt=""/><div class="Navbar__HoverMenu-sc-sxfljo-16 hOsskx"><ul class="Navbar__HoverMenuInner-sc-sxfljo-17 kMGA-dM"><img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDE2IDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNOCAwTDE2IDhIMEw4IDBaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K" alt="" class="Navbar__TriangleTop-sc-sxfljo-18 jZEECk"/><a href="https://pusher.com/docs"><li><h4 class="Text__Heading4-sc-73ytnd-3 hZlFEr">Docs</h4><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Read the docs to learn how to use our products</p></li></a><a href="/tutorials/"><li><h4 class="Text__Heading4-sc-73ytnd-3 hZlFEr">Tutorials</h4><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Explore our tutorials to build apps with Pusher products</p></li></a><a href="https://docs.bird.com/pusher"><li><h4 class="Text__Heading4-sc-73ytnd-3 hZlFEr">Support</h4><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Reach out to our support team for help and advice</p></li></a><a href="/glossary/"><li><h4 class="Text__Heading4-sc-73ytnd-3 hZlFEr">Glossary</h4><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Get familiar with Pusher-specific terminology</p></li></a></ul></div></li><li class="Text__Paragraph-sc-73ytnd-5 bAMNpF"><a href="/user-stories/"><span>User stories</span></a></li><li class="Text__Paragraph-sc-73ytnd-5 bAMNpF"><a href="/blog/"><span>Blog</span></a></li><li class="Text__Paragraph-sc-73ytnd-5 bAMNpF"><span>Pricing</span><img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHZpZXdCb3g9IjAgMCAxNiAxNiIgd2lkdGg9IjE2IiBoZWlnaHQ9IjE2IiByb2xlPSJpbWciPjxwYXRoIHN0cm9rZT0iIzMwMEQ0RiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0zLjMzMyA2TDggMTEuMzMzIDEyLjY2NyA2Ij48L3BhdGg+PC9zdmc+Cg==" alt=""/><div class="Navbar__HoverMenu-sc-sxfljo-16 hOtdIe"><ul class="Navbar__HoverMenuInner-sc-sxfljo-17 kMGA-dM"><img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iOCIgdmlld0JveD0iMCAwIDE2IDgiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNOCAwTDE2IDhIMEw4IDBaIiBmaWxsPSJ3aGl0ZSIvPgo8L3N2Zz4K" alt="" class="Navbar__TriangleTop-sc-sxfljo-18 jZEECk"/><a href="/channels/pricing/"><li><svg width="152" height="26" viewBox="0 0 152 26" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M42.3518 4.86432C45.6438 4.86432 48.2014 7.12315 48.5569 10.4016L45.3324 10.9327C44.9976 8.96201 43.931 7.85456 42.3479 7.85456C40.1005 7.85456 38.7666 9.75933 38.7666 12.9486C38.7666 16.1378 40.1005 18.0426 42.3479 18.0426C44.0153 18.0426 45.0833 16.8692 45.3726 14.7202L48.5971 15.2746C48.1975 18.752 45.7502 21.0328 42.3479 21.0328C38.1879 21.0328 35.4707 17.8436 35.4707 12.9486C35.4707 8.05357 38.1918 4.86432 42.3518 4.86432Z" fill="#300D4F"></path><path d="M51.5361 5.19647H54.8281V11.27H59.8771V5.19647H63.1691V20.7034H59.8771V14.2551H54.8281V20.7008H51.5361V5.19647Z" fill="#300D4F"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M69.7069 18.2867H75.668L76.4907 20.7006H79.7606L74.1991 5.19373H71.1744L65.6143 20.7006H68.8842L69.7069 18.2867ZM72.7085 9.69221L74.6653 15.4078H70.7076L72.6644 9.69221H72.7085Z" fill="#300D4F"></path><path d="M82.1826 5.19647H85.5564L90.8311 15.0524H90.8752V5.19647H94.1672V20.7034H90.7895L85.5187 10.8436H85.4746V20.7008H82.1826V5.19647Z" fill="#300D4F"></path><path d="M98.2393 5.19647H101.621L106.892 15.0524H106.936V5.19647H110.228V20.7034H106.847L101.577 10.8436H101.531V20.7008H98.2393V5.19647Z" fill="#300D4F"></path><path d="M114.298 5.19647H124.328V8.20869H117.59V11.354H123.727V14.2331H117.59V17.6886H124.35V20.7008H114.298V5.19647Z" fill="#300D4F"></path><path d="M127.774 5.19647H131.066V17.6886H137.65V20.7008H127.774V5.19647Z" fill="#300D4F"></path><path d="M142.831 14.8974C143.254 17.2015 144.162 18.0918 146.238 18.0918C147.774 18.0918 148.64 17.5375 148.64 16.5631C148.64 15.4776 147.907 14.9465 145.304 14.06C141.679 12.8415 140.323 11.535 140.323 9.25292C140.323 6.66844 142.503 4.86835 145.594 4.86835C148.64 4.86835 151.02 6.70591 151.511 9.43125L148.307 10.1174C147.885 8.54477 147.017 7.81336 145.594 7.81336C144.37 7.81336 143.569 8.36773 143.569 9.23483C143.569 10.0321 144.236 10.4754 146.554 11.2507C148.488 11.9149 149.89 12.6463 150.714 13.4656C151.538 14.2849 151.936 15.3045 151.936 16.567C151.936 19.2471 149.601 21.0407 146.198 21.0407C142.483 21.0407 140.171 19.136 139.614 15.5926L142.831 14.8974Z" fill="#300D4F"></path><path d="M16.4947 1.29257L14.2628 0.0145427C14.2291 -0.00484757 14.1875 -0.00484757 14.1538 0.0145427L11.8947 1.31324C11.861 1.33263 11.8194 1.33263 11.7857 1.31324L9.5266 0.0145427C9.49287 -0.00484757 9.45132 -0.00484757 9.4176 0.0145427L7.18574 1.29257C7.16872 1.30222 7.1582 1.32023 7.1582 1.33974C7.1582 1.35924 7.16872 1.37725 7.18574 1.3869L11.8078 4.05279C11.8248 4.06175 11.8452 4.06175 11.8623 4.05279L16.4895 1.39207C16.5099 1.38452 16.5238 1.36564 16.5249 1.34402C16.526 1.3224 16.5142 1.30218 16.4947 1.29257Z" fill="#6A52FF"></path><path d="M21.2308 4.02081L18.9989 2.73891C18.9652 2.71952 18.9236 2.71952 18.8899 2.73891L11.8946 6.76036C11.8609 6.77975 11.8193 6.77975 11.7856 6.76036L4.79027 2.73891C4.75654 2.71952 4.71499 2.71952 4.68127 2.73891L2.44941 4.02081C2.43239 4.03046 2.42188 4.04847 2.42188 4.06798C2.42188 4.08749 2.43239 4.10549 2.44941 4.11514L11.8076 9.49862C11.8244 9.50888 11.8454 9.50888 11.8621 9.49862L21.2256 4.11514C21.2432 4.10646 21.2547 4.08901 21.2558 4.06948C21.2569 4.04995 21.2473 4.03136 21.2308 4.02081Z" fill="#6A52FF"></path><path d="M14.209 10.9392V13.5055C14.2092 13.5249 14.2196 13.5426 14.2364 13.5522C14.2533 13.5618 14.2739 13.5617 14.2907 13.5521L23.6542 8.1686C23.6711 8.15919 23.6815 8.14137 23.6814 8.12208V5.61901C23.6815 5.58017 23.6608 5.54423 23.6271 5.52476C23.5933 5.50529 23.5517 5.50525 23.5179 5.52467L14.2635 10.8448C14.2297 10.8643 14.2089 10.9003 14.209 10.9392Z" fill="#6A52FF"></path><path d="M14.2907 18.9964L23.6542 13.6129C23.6709 13.6027 23.6812 13.5847 23.6814 13.5651V11.0646C23.6815 11.0258 23.6608 10.9898 23.6271 10.9704C23.5933 10.9509 23.5517 10.9509 23.5179 10.9703L14.2635 16.2917C14.2295 16.311 14.2086 16.3471 14.209 16.3861V18.9512C14.2096 18.9702 14.2202 18.9876 14.237 18.9969C14.2537 19.0061 14.2741 19.0059 14.2907 18.9964Z" fill="#6A52FF"></path><path d="M11.8405 22.9415V12.3012C11.8409 12.2622 11.8201 12.2261 11.786 12.2069L9.63592 10.9702C9.60215 10.9508 9.56052 10.9508 9.52678 10.9703C9.49303 10.9897 9.47231 11.0257 9.47242 11.0645V21.5808C9.47254 21.6196 9.45181 21.6555 9.41807 21.675C9.38432 21.6945 9.3427 21.6945 9.30893 21.6751L7.15882 20.4384C7.12499 20.419 7.1042 20.383 7.10432 20.3441V9.57714C7.10444 9.53824 7.08365 9.50226 7.04982 9.48281L4.89971 8.24743C4.86593 8.22801 4.82431 8.22804 4.79057 8.24751C4.75682 8.26698 4.73609 8.30292 4.73621 8.34176V18.8567C4.73633 18.8956 4.7156 18.9315 4.68186 18.951C4.64811 18.9704 4.60649 18.9705 4.57272 18.9511L2.42261 17.7157C2.38878 17.6962 2.36799 17.6602 2.36811 17.6213V6.84922C2.36822 6.81032 2.34743 6.77434 2.31361 6.75489L0.163497 5.52467C0.129722 5.50525 0.0881023 5.50529 0.0543566 5.52476C0.020611 5.54423 -0.000117278 5.58017 6.92109e-07 5.61901V19.0144C-9.78843e-05 19.0337 0.01034 19.0515 0.0272501 19.0609L11.8081 25.8374C11.8248 25.8477 11.8459 25.8477 11.8626 25.8374L23.6486 19.0609C23.6655 19.0515 23.676 19.0337 23.6759 19.0144V16.5113C23.676 16.4725 23.6553 16.4365 23.6215 16.4171C23.5878 16.3976 23.5461 16.3976 23.5124 16.417L12.004 23.0358C11.9703 23.0552 11.9286 23.0552 11.8949 23.0357C11.8611 23.0163 11.8404 22.9803 11.8405 22.9415Z" fill="#6A52FF"></path></svg><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Build scalable realtime features</p></li></a><a href="/beams/pricing/"><li><svg width="107" height="28" viewBox="0 0 107 28" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M11.6506 5.7014L9.52966 6.9333C9.49647 6.95258 9.47597 6.98816 9.47583 7.02671V25.9249C9.47613 25.944 9.48635 25.9615 9.50275 25.971L11.7313 27.2652C11.7478 27.2748 11.7682 27.2748 11.7848 27.2654C11.8014 27.2559 11.8118 27.2383 11.8121 27.2191V5.79481C11.8119 5.75618 11.7914 5.72056 11.7581 5.7013C11.7248 5.68205 11.6838 5.68209 11.6506 5.7014Z" fill="#2AE9AA"></path><path d="M14.2774 25.7937V23.3745C14.2771 23.3358 14.2973 23.2999 14.3304 23.2804C14.3634 23.2609 14.4043 23.2608 14.4375 23.2802L16.4313 24.4433C16.4638 24.463 16.4838 24.4986 16.4838 24.5369C16.4838 24.5753 16.4638 24.6109 16.4313 24.6306L14.3575 25.8436C14.3405 25.8535 14.3194 25.8532 14.3027 25.8428C14.286 25.8324 14.2763 25.8135 14.2774 25.7937Z" fill="#2AE9AA"></path><path d="M14.1478 20.4191V17.944C14.148 17.9057 14.1689 17.8703 14.2027 17.8512C14.2365 17.8321 14.2781 17.8321 14.3119 17.8513L21.1012 21.7037C21.1354 21.7228 21.1564 21.7585 21.1564 21.7971C21.1564 21.8357 21.1354 21.8713 21.1012 21.8905L18.9206 23.1294C18.9036 23.1387 18.8829 23.1387 18.8659 23.1294L14.1752 20.4675C14.1572 20.458 14.1465 20.4391 14.1478 20.4191Z" fill="#2AE9AA"></path><path d="M14.2774 15.0086V12.5173C14.277 12.4784 14.2977 12.4424 14.3315 12.4228C14.3654 12.4033 14.4072 12.4032 14.4411 12.4226L23.6975 17.719C23.7314 17.7388 23.7522 17.7748 23.7521 17.8137V20.3673C23.7523 20.3867 23.7419 20.4047 23.725 20.4145C23.7081 20.4243 23.6872 20.4243 23.6702 20.4146L14.3047 15.0559C14.2874 15.0464 14.2769 15.0282 14.2774 15.0086Z" fill="#2AE9AA"></path><path d="M14.2773 9.58038V7.08903C14.277 7.0502 14.2977 7.01416 14.3315 6.9946C14.3654 6.97503 14.4072 6.97494 14.4411 6.99436L23.6975 12.2908C23.7314 12.3099 23.7523 12.3456 23.7521 12.3841V14.9391C23.7523 14.9585 23.7419 14.9765 23.725 14.9863C23.7081 14.9961 23.6872 14.9961 23.6702 14.9864L14.3046 9.62501C14.288 9.61616 14.2776 9.59906 14.2773 9.58038Z" fill="#2AE9AA"></path><path d="M6.97893 8.41349L4.85568 9.64537C4.82223 9.66445 4.80161 9.70015 4.80176 9.73878V23.211C4.80206 23.23 4.8123 23.2475 4.82872 23.257L7.05577 24.5511C7.07272 24.5607 7.0934 24.5605 7.11025 24.5508C7.12709 24.5411 7.13763 24.5233 7.138 24.5038V8.50825C7.13705 8.47054 7.11686 8.43596 7.08455 8.41671C7.05224 8.39746 7.01234 8.39625 6.97893 8.41349Z" fill="#2AE9AA"></path><path d="M2.17062 11.1316L0.0539015 12.3627C0.0204852 12.3817 -0.000103667 12.4174 4.09983e-05 12.456V20.4959C-0.000740985 20.5156 0.00971518 20.534 0.0269712 20.5433L2.25545 21.8366C2.27219 21.8463 2.29282 21.8463 2.30952 21.8365C2.32622 21.8267 2.33641 21.8087 2.33624 21.7893V11.2263C2.3366 11.1866 2.31551 11.1497 2.28112 11.1301C2.24674 11.1104 2.20445 11.111 2.17062 11.1316Z" fill="#2AE9AA"></path><path d="M0.0005809 9.37832V6.82351C0.000139741 6.78482 0.0211368 6.74899 0.0552989 6.73014L11.8238 0.0142972C11.8577 -0.00476574 11.8993 -0.00476574 11.9332 0.0142972L23.6976 6.73285C23.7317 6.7517 23.7527 6.78752 23.7523 6.82622V9.37832C23.7525 9.39774 23.7421 9.41577 23.7251 9.42556C23.7082 9.43535 23.6872 9.43539 23.6702 9.42568L11.9058 2.70848C11.8888 2.69908 11.8681 2.69908 11.8511 2.70848L0.0867617 9.42568C0.069594 9.43767 0.0470028 9.43887 0.0286333 9.42878C0.0102637 9.41868 -0.000638621 9.39907 0.0005809 9.37832Z" fill="#2AE9AA"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M35.4341 6.5199H41.8652C44.426 6.5199 46.2665 8.1847 46.2665 10.4816C46.2665 11.6823 45.6954 12.6789 44.7648 13.2411V13.2838C46.0341 13.8732 46.8168 15.1386 46.8168 16.6767C46.8168 19.7788 44.9763 21.2691 41.189 21.2691H35.4341V6.5199ZM41.4223 12.3969C42.5437 12.3969 43.1576 11.8489 43.1576 10.8381C43.1576 9.848 42.5437 9.29996 41.4223 9.29996H38.5669V12.4021L41.4223 12.3969ZM43.7077 16.6532C43.7077 17.8967 43.0938 18.4861 41.7608 18.4861L38.5654 18.4822V14.8631H41.7816C43.0302 14.8631 43.7077 15.4899 43.7077 16.6532Z" fill="#300D4F"></path><path d="M49.8616 6.51831H59.4051V9.38389H52.9934V12.3761H58.834V15.115H52.9934V18.4097H59.4259V21.2753H49.8616V6.51831Z" fill="#300D4F"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M65.0104 18.972H70.681L71.4585 21.2676H74.5735L69.2845 6.51831H66.407L61.1167 21.2689H64.2317L65.0104 18.972ZM67.8649 10.7967L69.7274 16.2332H65.9608L67.8233 10.7967H67.8649Z" fill="#300D4F"></path><path d="M76.8792 6.51831H80.3485L84.5018 16.4425H84.5433L88.707 6.51831H92.1763V21.2689H89.1081V12.1667H89.0666L85.1949 21.2689H83.8399L79.9889 12.1667H79.9474V21.2689H76.8792V6.51831Z" fill="#300D4F"></path><path d="M98.0578 15.7484C98.4602 17.9457 99.3272 18.7833 101.295 18.7833C102.755 18.7833 103.58 18.2559 103.58 17.3292C103.58 16.2951 102.882 15.791 100.406 14.9483C96.9572 13.785 95.6671 12.5455 95.6671 10.3753C95.6671 7.91039 97.7437 6.20422 100.681 6.20422C103.58 6.20422 105.844 7.95304 106.31 10.5446L103.262 11.1909C102.86 9.69539 102.036 9 100.681 9C99.5128 9 98.7561 9.52607 98.7561 10.3481C98.7561 11.1069 99.3908 11.5282 101.591 12.2663C103.431 12.8983 104.764 13.5924 105.548 14.3731C106.332 15.1538 106.716 16.1219 106.716 17.3227C106.716 19.8716 104.494 21.5791 101.257 21.5791C97.7243 21.5791 95.5243 19.7695 94.9948 16.396L98.0578 15.7484Z" fill="#300D4F"></path></svg><p class="Text__Paragraph-sc-73ytnd-5 lcqCHo">Programmatic push notifications</p></li></a></ul></div></li></ul><ul class="Navbar__RightMenu-sc-sxfljo-12 hMvIsa"><li class="Text__Paragraph-sc-73ytnd-5 Navbar__SignIn-sc-sxfljo-13 bAMNpF hJfXrn"><a href="https://dashboard.pusher.com/"><span>Sign in</span></a></li><li><a href="https://dashboard.pusher.com/accounts/sign_up"><button class="Buttons__Button-sc-62rjb8-0 deYSNt">Sign up</button></a></li></ul><div role="button" tabindex="0" aria-label="Burger Menu" class="Navbar__BurgerMenuContainer-sc-sxfljo-14 hIEYyq"><span class="Navbar__BurgerMenu-sc-sxfljo-15 ddKFPY"></span></div></div></div></div></div><form action="/search" class="SearchBar__Container-sc-1rbmdkr-0 cWzLmV"><a aria-label="Blog" class="SearchBar__BrandLink-sc-1rbmdkr-1 dfkKQm" href="/blog/"><svg width="65" height="20" viewBox="0 0 65 20" fill="none"><path d="M6.63 19.1C11.258 19.1 13.546 17.228 13.546 13.406C13.546 11.508 12.584 9.97401 10.998 9.24601V9.19401C12.168 8.51801 12.87 7.29601 12.87 5.78801C12.87 2.95401 10.582 0.900009 7.436 0.900009H0V19.1H6.63ZM3.848 4.33201H6.916C8.268 4.33201 9.022 5.03401 9.022 6.25601C9.022 7.47801 8.268 8.15401 6.916 8.15401H3.848V4.33201ZM3.848 11.196H7.384C8.866 11.196 9.698 12.002 9.698 13.38C9.698 14.914 8.97 15.642 7.384 15.642H3.848V11.196Z" fill="currentColor"></path><path d="M30.5602 19.1V15.564H21.2782V0.900009H17.4302V19.1H30.5602Z" fill="currentColor"></path><path d="M40.1903 19.49C44.5323 19.49 47.6263 15.772 47.6263 10C47.6263 4.22801 44.5323 0.51001 40.1903 0.51001C35.8483 0.51001 32.7803 4.22801 32.7803 10C32.7803 15.772 35.8223 19.49 40.1903 19.49ZM40.1903 15.954C37.9543 15.954 36.6283 13.77 36.6283 10C36.6283 6.23001 37.9543 4.04601 40.1903 4.04601C42.4263 4.04601 43.7783 6.23001 43.7783 10C43.7783 13.77 42.4263 15.954 40.1903 15.954Z" fill="currentColor"></path><path d="M57.5945 19.49C61.7545 19.49 64.5625 16.5 64.5625 11.95V9.48001H57.7245V12.6H60.9225C60.8705 14.732 59.6225 15.954 57.5945 15.954C55.0985 15.954 53.5385 13.718 53.5385 10C53.5385 6.28201 55.0985 4.04601 57.5945 4.04601C59.2845 4.04601 60.5065 5.26801 60.8965 7.34801L64.6665 6.75001C64.1985 3.05801 61.2865 0.51001 57.5945 0.51001C52.8365 0.51001 49.6905 4.25401 49.6905 10C49.6905 15.772 52.8365 19.49 57.5945 19.49Z" fill="currentColor"></path></svg></a><div class="SearchBar__FormContainer-sc-1rbmdkr-2 bpeDTq"><input type="text" name="query" placeholder="Search all Pusher content" class="SearchBar__Input-sc-1rbmdkr-3 dUFhcL" value=""/><button type="submit" class="Buttons__Button-sc-62rjb8-0 SearchBar__Submit-sc-1rbmdkr-4 jvSrRs eGOtaE">Search</button></div></form><section class="strapiBlogPostSlug__Container-sc-3royxi-0 fIZfrU"><div class="Utils__OnlyOnDesktop-sc-btxiab-1 strapiBlogPostSlug__DesktopView-sc-3royxi-13 jbxepG iQxqSG"><aside class="strapiBlogPostSlug__Info-sc-3royxi-2 iOfIXf"><div class="strapiBlogPostSlug__InfoContent-sc-3royxi-3 ciqtmA"><p class="Typography__P-sc-1bnioie-10 strapiBlogPostSlug__InfoHeading-sc-3royxi-4 fxSXlu dyACfP">Authors</p><a class="strapiBlogPostSlug__Author-sc-3royxi-7 fSgBox" href="/author/jim-fisher/">Jim Fisher<!-- --> <!-- -->(Technical Product Manager at Pusher)</a></div><div class="strapiBlogPostSlug__InfoContent-sc-3royxi-3 ciqtmA"><div class="strapiBlogPostSlug__InfoContent-sc-3royxi-3 ciqtmA"><p class="Typography__P-sc-1bnioie-10 strapiBlogPostSlug__InfoHeading-sc-3royxi-4 fxSXlu dyACfP">8<!-- --> minute read</p></div><div class="strapiBlogPostSlug__InfoContent-sc-3royxi-3 ciqtmA"><p class="Typography__P-sc-1bnioie-10 strapiBlogPostSlug__InfoHeading-sc-3royxi-4 fxSXlu dyACfP">Last updated</p>11th October 2016<!-- --> (published 12th May 2016)</div></div><div class="strapiBlogPostSlug__InfoContent-sc-3royxi-3 ciqtmA"><p class="Typography__P-sc-1bnioie-10 strapiBlogPostSlug__InfoHeading-sc-3royxi-4 fxSXlu dyACfP">Categories</p><div class="strapiBlogPostSlug__ItemTags-sc-3royxi-8 bxqSel"><div class="Pill-sc-1gtnmru-0 egCjPX">Engineering</div></div></div><div class="strapiBlogPostSlug__InfoContent-sc-3royxi-3 ciqtmA"><p class="Typography__P-sc-1bnioie-10 strapiBlogPostSlug__InfoHeading-sc-3royxi-4 fxSXlu dyACfP">Share</p><div class="strapiBlogPostSlug__ItemTags-sc-3royxi-8 bxqSel"><a href="https://twitter.com/share?text=Check out this blog post on Pusher&url=undefined" target="__blank" rel="nofollow" class="strapiBlogPostSlug__ShareButton-sc-3royxi-9 gzhCCA">Share on Twitter</a><a href="https://discord.gg/K3svTwjRqD" target="__blank" class="strapiBlogPostSlug__ShareButton-sc-3royxi-9 gzhCCA">Discuss on Discord</a></div></div><div class="strapiBlogPostSlug__InfoContent-sc-3royxi-3 strapiBlogPostSlug__Toc-sc-3royxi-5 gbnMkX RELxG"><div class="TableOfContent__MobileWrapper-sc-bf7dii-0 bVuTIP"><select class="TableOfContent__Select-sc-bf7dii-1 gzMOiX"><option value="#introduction">Introduction</option><option value="#the-message-bus">The message bus</option><option value="#performance-testing-the-message-bus">Performance testing the message bus</option><option value="#isolating-the-garbage-collection-pauses">Isolating the garbage collection pauses</option><option value="#understanding-the-ghc-garbage-collector">Understanding the GHC garbage collector</option><option value="#three-non-fixes">Three non-fixes</option><option value="#conclusion">Conclusion</option></select></div><ul class="TableOfContent__DesktopWrapper-sc-bf7dii-2 fqLCGN"><li class="TableOfContent__Heading-sc-bf7dii-3 jpodUS"><a href="#introduction" class="TableOfContent__HeadingLink-sc-bf7dii-4 hQgFPV">Introduction</a></li><li class="TableOfContent__Heading-sc-bf7dii-3 jpodUS"><a href="#the-message-bus" class="TableOfContent__HeadingLink-sc-bf7dii-4 hQgFPV">The message bus</a></li><li class="TableOfContent__Heading-sc-bf7dii-3 jpodUS"><a href="#performance-testing-the-message-bus" class="TableOfContent__HeadingLink-sc-bf7dii-4 hQgFPV">Performance testing the message bus</a></li><li class="TableOfContent__Heading-sc-bf7dii-3 jpodUS"><a href="#isolating-the-garbage-collection-pauses" class="TableOfContent__HeadingLink-sc-bf7dii-4 hQgFPV">Isolating the garbage collection pauses</a></li><li class="TableOfContent__Heading-sc-bf7dii-3 jpodUS"><a href="#understanding-the-ghc-garbage-collector" class="TableOfContent__HeadingLink-sc-bf7dii-4 hQgFPV">Understanding the GHC garbage collector</a></li><li class="TableOfContent__Heading-sc-bf7dii-3 jpodUS"><a href="#three-non-fixes" class="TableOfContent__HeadingLink-sc-bf7dii-4 hQgFPV">Three non-fixes</a></li><li class="TableOfContent__Heading-sc-bf7dii-3 jpodUS"><a href="#conclusion" class="TableOfContent__HeadingLink-sc-bf7dii-4 hQgFPV">Conclusion</a></li></ul></div></aside><div class="strapiBlogPostSlug__Content-sc-3royxi-6 bFWuQN"><div class="strapiBlogPostSlug__IntroContainer-sc-3royxi-1 ewdxkq"><h1 class="Typography__H1-sc-1bnioie-0 fvUeZd">Low latency, large working set, and GHC’s garbage collector: pick two of three</h1><div class="Utils__OnlyOnMobile-sc-btxiab-0 eiLoiF"><p class="Typography__P-sc-1bnioie-10 fxSXlu">Pusher makes it easy for developers to reliably deliver data at scale. A few features we are working on required a rewrite of our internal message bus, but we knew anything we build has to perform as reliably as the existing platform. Our chosen language for this job was Haskell, compiled with GHC. Haskell, unusually \[…\]</p></div></div><h2 id="introduction" class="Typography__H2-sc-1bnioie-1 strapiBlogPostSlug__HiddenIntroductionHeading-sc-3royxi-10 jaoFLa cfmUCS">Introduction</h2><div class="RenderMarkdown__Wrapper-sc-1u2193p-0 bPYiaA"><p class="Typography__P-sc-1bnioie-10 fxSXlu">Pusher makes it easy for developers to reliably deliver data at scale. A few features we are working on required a rewrite of our internal message bus, but we knew anything we build has to perform as reliably as the existing platform. Our chosen language for this job was Haskell, compiled with GHC. Haskell, unusually obsessed with correctness, was a good choice for our focus on reliability. GHC was a good choice as a compiler with a reputation for good performance. But our performance tests showed that our new implementation had performance problems. It suffered from high worst-case latency: the time between sending and receiving a message could be in the hundreds of milliseconds.</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">This blog post documents our investigation of these latency problems. Our findings have some implications for designing similar systems using GHC.</p>
|
||
<h2 id="the-message-bus" class="Typography__H2-sc-1bnioie-1 Typography__H2WithCopyStyling-sc-1bnioie-6 jaoFLa kjHJGs">The message bus<button class="hocs__CopyLinkButton-sc-d5soun-0 eLZtaH copy"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10.8313 15.5025L8.64814 17.6857C6.89602 19.4378 4.05925 19.4378 2.31409 17.6857C0.56197 15.9336 0.56197 13.0968 2.31409 11.3517L4.49728 9.16846" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.16891 4.49728L11.3521 2.31409C13.1042 0.56197 15.941 0.56197 17.6862 2.31409C19.4383 4.06621 19.4383 6.90297 17.6862 8.64814L15.503 10.8313" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M7.2177 12.781L12.78 7.21875" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></button></h2>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">Conceptually, our in-memory message store is a buffer. New messages get pushed on one end, and old messages get popped off at the other. Systems can ask for the message history without popping them off, so the process must also be able to traverse the buffer efficiently.</p>
|
||
<h2 id="performance-testing-the-message-bus" class="Typography__H2-sc-1bnioie-1 Typography__H2WithCopyStyling-sc-1bnioie-6 jaoFLa kjHJGs">Performance testing the message bus<button class="hocs__CopyLinkButton-sc-d5soun-0 eLZtaH copy"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10.8313 15.5025L8.64814 17.6857C6.89602 19.4378 4.05925 19.4378 2.31409 17.6857C0.56197 15.9336 0.56197 13.0968 2.31409 11.3517L4.49728 9.16846" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.16891 4.49728L11.3521 2.31409C13.1042 0.56197 15.941 0.56197 17.6862 2.31409C19.4383 4.06621 19.4383 6.90297 17.6862 8.64814L15.503 10.8313" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M7.2177 12.781L12.78 7.21875" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></button></h2>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">After implementing this system, we implemented some comprehensive performance tests. Two performance characteristics we care about are <em>throughput</em> and <em>latency</em>. Throughput means messages per second, and latency means the time between sending a message and receiving it. We pushed millions of realistic messages through the system, measuring the latency of each message using wall-clock time. Finally, we charted the distribution of these using the <a href="https://www.google.com/url?q=http://hackage.haskell.org/package/statistics&sa=D&ust=1462899478183000&usg=AFQjCNG2DeFFf1Nq012inldwCSSRcXDnPA" class="Typography__A-sc-1bnioie-11 eVlkaw">statistics</a> package.</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">Pusher’s existing message bus has high throughput and low latency. Our replacement has to achieve the same low latency, but our tests showed that the 99th percentile latency was surprisingly high. Most messages traversed the new system within 5 milliseconds. But a significant few took several hundreds of milliseconds. This is too high for Pusher’s realtime platform, which currently achieves a 99th percentile of around 100 milliseconds.</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">What was causing this poor worst-case? To investigate, we needed more visibility of what our program was doing. GHC provides some good observability tools. One of these, ThreadScope, gives you a microsecond-level visual history of one run of your program. Here’s the chart of one run of our performance benchmark:</p>
|
||
<div class="ZoomImage__ZoomImageWrapper-sc-agae5n-0 oXmDm"><div aria-owns="rmiz-modal-" data-rmiz=""><div data-rmiz-content="not-found" style="visibility:visible"><img src="https://general-pusher-cms.s3.amazonaws.com/blog/threadscope_1_1_913x300_6103a22bd1.png" alt="threadscope_1" class="ZoomImage__CustomImage-sc-agae5n-1 QEXmd"/></div></div></div>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">The chart shows the history of one run of our benchmark program. Time runs along the x-axis. The pink lines mark when the system receives messages, and so the blocks of pink lines are periods of ‘productive’ work.</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">What are those large gaps between sections of productive work? They represent the cause of the worst-case latencies in our tests. During these periods, sent messages were waiting to be forwarded.</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">The chart marks garbage collection cycles in orange, each around 8 milliseconds long. These sections exactly correspond to the periods where our program did no work! All our pauses were due to garbage collection.</p>
|
||
<h2 id="isolating-the-garbage-collection-pauses" class="Typography__H2-sc-1bnioie-1 Typography__H2WithCopyStyling-sc-1bnioie-6 jaoFLa kjHJGs">Isolating the garbage collection pauses<button class="hocs__CopyLinkButton-sc-d5soun-0 eLZtaH copy"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10.8313 15.5025L8.64814 17.6857C6.89602 19.4378 4.05925 19.4378 2.31409 17.6857C0.56197 15.9336 0.56197 13.0968 2.31409 11.3517L4.49728 9.16846" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.16891 4.49728L11.3521 2.31409C13.1042 0.56197 15.941 0.56197 17.6862 2.31409C19.4383 4.06621 19.4383 6.90297 17.6862 8.64814L15.503 10.8313" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M7.2177 12.781L12.78 7.21875" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></button></h2>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">The question we needed to answer was: what determines the length of a garbage collection pause? We took two approaches to answering this: white box and black box. Black box testing meant fiddling with our benchmarks, watching the change in garbage collection pauses. White boxing meant understanding the garbage collector in the GHC runtime.</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">Our black-box tests <a href="https://github.com/jameshfisher/ghc%5Fgc%5Fbenchmarks" class="Typography__A-sc-1bnioie-11 eVlkaw">simplified our program to the simplest case which exhibited these latencies.</a> Our real-world program can hold many interrelated buffers, with messages of many sizes, which are expired by multiple policies. The simplified program just works with 1-kilobyte messages in a <code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">Data.Map.Strict</code>, indexed by send time. It inserts new messages in time order, and pops old ones off, to limit the structure at 200,000 messages:</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">module Main (main) where</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">import qualified Control.Exception as Exception
|
||
import qualified Control.Monad as Monad
|
||
import qualified Data.ByteString as ByteString
|
||
import qualified Data.Map.Strict as Map</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">data Msg = Msg !Int !ByteString.ByteString</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">type Chan = Map.Map Int ByteString.ByteString</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">message :: Int -> Msg
|
||
message n = Msg n (ByteString.replicate 1024 (fromIntegral n))</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">pushMsg :: Chan -> Msg -> IO Chan
|
||
pushMsg chan (Msg msgId msgContent) =
|
||
Exception.evaluate $
|
||
let
|
||
inserted = Map.insert msgId msgContent chan
|
||
in
|
||
if 200000 < Map.size inserted
|
||
then Map.deleteMin inserted
|
||
else inserted</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">main :: IO ()
|
||
main = Monad.foldM_ pushMsg Map.empty (map message [1..1000000])</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">We compiled and ran this program using:</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">$ ghc --version
|
||
The Glorious Glasgow Haskell Compilation System, version 7.10.3
|
||
$ ghc -O2 -optc-O3 Main.hs
|
||
$ ./Main +RTS -s
|
||
3,116,460,096 bytes allocated in the heap
|
||
385,101,600 bytes copied during GC
|
||
235,234,800 bytes maximum residency (14 sample(s))
|
||
124,137,808 bytes maximum slop
|
||
600 MB total memory in use (0 MB lost due to fragmentation)</p>
|
||
<pre><div class="CodeSnippet__CodeBlock-sc-ov4fyy-0 gMoEsU"><button class="CodeSnippet__Header-sc-ov4fyy-2 kjuemt"><p>bash</p></button><div class="CodeSnippet__Container-sc-ov4fyy-3 bIrJuJ"><pre class="codeStyle" node="[object Object]" style="display:block;overflow-x:auto;padding:0.5em;background:#011627;color:#d6deeb"><code class="language-bash" style="white-space:pre"><span class="comment linenumber react-syntax-highlighter-line-number" style="display:inline-block;min-width:1.25em;padding-right:1em;text-align:right;user-select:none">1</span><span>Tot time (elapsed) Avg pause Max pause</span></code></pre></div><div class="CodeSnippet__Footer-sc-ov4fyy-4 dkDpiy"><button class="CodeSnippet__CopyCodeButton-sc-ov4fyy-5 iRZIYR">Copy</button></div></div></pre>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">Gen 0 6558 colls, 0 par 0.238s 0.280s 0.0000s 0.0012s
|
||
Gen 1 14 colls, 0 par 0.179s 0.250s 0.0179s 0.0515s</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">INIT time 0.000s ( 0.000s elapsed)
|
||
MUT time 0.652s ( 0.745s elapsed)
|
||
GC time 0.417s ( 0.530s elapsed)
|
||
EXIT time 0.010s ( 0.052s elapsed)
|
||
Total time 1.079s ( 1.326s elapsed)</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">%GC time 38.6% (40.0% elapsed)</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">Alloc rate 4,780,213,353 bytes per MUT second</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">Productivity 61.4% of total user, 49.9% of total elapsed</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">GHC’s runtime can output various statistics. Above, we print out garbage collection statistics with <code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">+RHS -s</code>. The important metric in the result is the ‘max pause’ of 0.0515s, or 51 milliseconds. This program still exhibits the same garbage collection pauses when examined in ThreadScope:</p>
|
||
<div class="ZoomImage__ZoomImageWrapper-sc-agae5n-0 oXmDm"><div aria-owns="rmiz-modal-" data-rmiz=""><div data-rmiz-content="not-found" style="visibility:visible"><img src="https://general-pusher-cms.s3.amazonaws.com/blog/threadscope_data_map_1_1093x300_9c527c005e.png" alt="threadscope_data_map" class="ZoomImage__CustomImage-sc-agae5n-1 QEXmd"/></div></div></div>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">We tried tweaking many variables to test their effects on this pause time, most of which had very little effect. Compiler optimization flags (<code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">-O</code>, <code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">-O2</code>) made little difference. GC options (<code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">-G</code>, <code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">-H</code>, <code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">-A</code>, <code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">-c</code>) made little difference (see below). Using different data structures made little difference (we also tried a <code class="CodeSnippet__Code-sc-ov4fyy-1 eDNcFJ">Data.Sequence</code> and a priority queue). Varying the size of messages made little difference (for reasons we’ll explain). Artificially increasing the amount of short-lived garbage did not increase the pause time (also for reasons we’ll explain).</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">Only one variable had a definite effect: the number of messages kept in the history. The relationship was roughly linear (or perhaps slightly worse):</p>
|
||
<div class="ZoomImage__ZoomImageWrapper-sc-agae5n-0 oXmDm"><div aria-owns="rmiz-modal-" data-rmiz=""><div data-rmiz-content="not-found" style="visibility:visible"><img src="https://general-pusher-cms.s3.amazonaws.com/blog/relationship_1_485x300_6c1c86f3b3.png" alt="relationship" class="ZoomImage__CustomImage-sc-agae5n-1 QEXmd"/></div></div></div>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">The message history in our program is our entire working set. The results above seemed to apply more generally to other programs: the size of the working set determined the length of the maximum pause. But why?</p>
|
||
<h2 id="understanding-the-ghc-garbage-collector" class="Typography__H2-sc-1bnioie-1 Typography__H2WithCopyStyling-sc-1bnioie-6 jaoFLa kjHJGs">Understanding the GHC garbage collector<button class="hocs__CopyLinkButton-sc-d5soun-0 eLZtaH copy"><svg width="20" height="20" viewBox="0 0 20 20" fill="none"><path d="M10.8313 15.5025L8.64814 17.6857C6.89602 19.4378 4.05925 19.4378 2.31409 17.6857C0.56197 15.9336 0.56197 13.0968 2.31409 11.3517L4.49728 9.16846" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9.16891 4.49728L11.3521 2.31409C13.1042 0.56197 15.941 0.56197 17.6862 2.31409C19.4383 4.06621 19.4383 6.90297 17.6862 8.64814L15.503 10.8313" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M7.2177 12.781L12.78 7.21875" stroke="#300D4F" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg></button></h2>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">The first important thing to know is that GHC’s garbage collector is <em>stop-the-world</em>. A stop-the-world garbage collector flips between two phases: a normal process execution phase where garbage is generated, and a garbage collection phase where garbage is collected. These are the two phases seen in the ThreadScope view of our processes, and it is these periods where ‘the world is stopped’ which cause our latency problem.</p>
|
||
<p class="Typography__P-sc-1bnioie-10 fxSXlu">The garbage collector is <em>generational</em>, which is an optimization to reduce the number of long collections on the entire heap. It organizes allocated objects into buckets by |