From f812af5c47688581446620e97ebb8a8b9e5d6134 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:57:29 +0530 Subject: [PATCH 1/6] Updated performance results in README.md --- README.md | 12 ++++-------- assets/latency_histogram.png | Bin 17584 -> 16132 bytes assets/req_sec_histogram.png | Bin 19107 -> 14231 bytes 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 7cf231f1..e2359711 100644 --- a/README.md +++ b/README.md @@ -42,14 +42,10 @@ Get started with the benchmarks: ## Benchmark Results - -| Server | Requests/sec | Latency (ms) | -| ---------------- | -----------: | -----------: | -| [Tailcall] | `2,890.68` | `34.69` | -| [Gqlgen] | `935.00` | `115.73` | -| [Apollo GraphQL] | `793.37` | `128.22` | -| [Netflix DGS] | `597.39` | `191.85` | - +| Server | Requests/sec | Latency (ms) | +|--------|--------------|--------------| +| apollo | 0 | 16.896666666666665 | +| tailcall | 0 | 602.0966666666667 | ### Throughput (Higher is better) diff --git a/assets/latency_histogram.png b/assets/latency_histogram.png index 99e3c219262c646b07563bbba60e8c762875e3ca..bf9d20884635374f0399c3c3f9732a654c852b58 100644 GIT binary patch literal 16132 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 literal 17584 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 diff --git a/assets/req_sec_histogram.png b/assets/req_sec_histogram.png index 25c3836492cd8d12e196657c5a6694ee7ee25fdc..1ee873dd014ba310f781726a16b86c32bc5932c4 100644 GIT binary patch literal 14231 zcmeHud035m+xCiw))uww&_;tLVoRc=NP|K}lcF>(R3cJop4Q5?$W%#4nv6|UqBOTE zQlvtqd6J}YHP5Z}p0{`J=X>7od*0#rj`w-q_m7>!(W3>`N#Ha>?U!EfA?}@LrA1mB(2@M4thlN zHl1>*s=hxlt3;+={_Tn?Rg>r3s!OXb=}Q$$&Uvs$pXbTOr&l8EmcFxl?0=!?gK1#( z1^a5(6ZT5E`U%SxKb*H9@$Llg&J&XEA637u=K0BFj=|SucRGunmY-igcw2!vJDGEA ztaq|3%6wT*c#Bl9w!~blMws1g?L{nWz=o2KZ@YJq@N3FEo`qQOlD}-muMYh8zEO4a zRC4aia(}rqjT2WSlRRceYh-g%D^6C$9capS*OLedk-O2ic6KzGQ8v;| z^3%JnDG?H8IhRx%TX3FNWxDr8dJElqc4}0e%qt-3)03Fa;f%97zkTBjM|0m-R8)-2 zQ75;}3|DY#Se&$DMOXA9JimXqpOcdlEUxkL#K$jziv0@1?`8cLF8`G2+{u_}7gOO* zR`h&MobG;-?AG5nx&N>%X<)LdY-A2ep?r2ER>l6qyUGp)R~QJ%+Zk}THgMohGx7qIl~xD_9} zDeLl@2+Bvup-SCwyCMG<_i5lkrkQ%a-vAD{Kzdbm{uk!Deu$2ijg0Ut8{6Fi*(Z#wOBd=xv1x z*T+lgkWU;o$?46t<)P+h-(C>1oalW~p^UxeTeeYwJ2QN0riY)zq}(9s%g$f4Vu@M? zo)2q0m+i~;ZpoeT47zI;*g9vkVZ?2L48*3!vq{f#e1H!=&mE@bIJWo|zH z{!W!gkf>6*@^o+7sT!kMOO1xsB#Ue{vVhWvep8k!@4{aO`WzV34K1884I1ZGvQNi} zO2pa9ttTA29*16}>~QOy7;A8-2$Qu%#$e0WZz8_(*m=|6DxzDm-Ps$I4<0yhfZP@n zer8{Qd(UV4vEI6X6>?MNG-Fb$tTX>+lH8LA500^$bFu$T=?*PdmP)SJc6y@LDk#x3 zZ3FZAf_h$2k5$|jtbB!9ZJzIRmTQk18Sm|Lh`n<4cwY-kWi;ra{eUEG@?8ae?8WT# zIHIM6T@`QG@X}t)XP_YHOf1f=5pHz&a4n0$efsoi)vMm#-cw1L-$Ge49q(>Qw)hN} zH8`+*E25O*&AG1yT!BrGTb%O!c)A`I@c7-8@Z*`d5#d<)6CSRpqT6XQ)pf+7yZZwY z#B%6puGi?kzSWzgrS(`orMIOt8qRLm_@uejoi*K*XqKKg@#Sj!n}7!FMTS#*lPP%1-Iq zNct84Y+Ax5i!3I^jomDw_PsX6iVUDx)H%}-qNnWHU?E(o%nN)%F_vjo#ep5A zp|SFaZ~%`1mp)u3pKjl9dusgSwuv4ZHw&Ltbn7K@m_Ah*O<=5E?!cuqrLkHoF-780 zxpr4A-+V-sOjS`~wB-599)BPA^r<#$bC|Y~kx@+lm4ik8-PmdJ{frES(S%!)#%?{I z``Y})lFE~%N%|MGqnQiyog`fsKOJvja0dz|hdcc#{kh}K)-uTTIs_epJ-a{a6mlTF z@$7!YTyj=-g0;+Kvp1WlAzwrEq5u&DE|yBOb~3N$k&XQMMV>!@j*K5hTy9$$5zl8L zVt?L&HS4xIIHUJ@DY3@{;-8oP>00q>+kJ4zbW(U zjS-EE!8a?_$wD-rK_rUM#>1QK>r+LQyqFXTy(sfh|N2~S_u+44dVue)%2?D8Mn6Jz zb@1V5M+!oR`$!}_6giuL)&eRMn<=7vr#`shsmY6~S2u3l0E)zNH+mye&NOAojaKcK z&aHZ|=W3Nl_%{12cXkwiD{52BnOEVFk-m6%qexVMSCZFxK?!Yzu16sT=ZWoCq5Ifz z#JCg1RZX{=J=y~v>Xeq1&0--@9I~Q&zp$L$!N?t4?tz2raCb`MjUiF`MgCKrD%`pl zo$xA;^fOKL;qaD&!$Kk?g{<8&VNc6N-jN2Di|lZTd-UiLvfS?O2F+iKtp3= zBfrQFRE9;)-`>|{I@?ag%boh1db&==wY)F3uC+W;QD~F-oyf>0R6rL~e+r`Hh41tj zs$4>>$o&Toz9gnMC&a~_Ky=6IMjCXE)9(u0(w0EEGfTG2MKNVeCI3tsDEbN54t!H?kq1VDhjjs370HR(eCG=w_On08?d7K@&3^9W^d{9rFdi2{IG?s z^Z1s%50j0x%=KDsPEe}gk{Rj;Dzj2ov5fiwKUc+BefhC+{mSm+UOdq{y1L~E5ZPSN z#8n2xh167^Gie+BfNedz{C*Wu!3q-Pv*)aCw=9k`T^(F9^7Dk6@SH_|&@t73l{-Bg z5ytI-if;l%kejt1A8L&E)UcU?x+lO;w6xv|)eT|i@5-HWLy=)pfQxrE*8qqWoW8s! zNDjcJ6xm)@W|4W;M$R{|KJm5)aRq(vze{r_Cnux5!~cfoPzu@f@odBe$_FCoA_Wwp z9=Hp_P!_TM1-6dnGkY@E+ah(KI`oOt`Dm?*z+55LAXmAVFX%E!cg@fIF}x(wG3RE_ z&I=Tx?1_dUg_9YxJ;-+=Ig#n5sGA1us8|T~^&2-nrLj2G#R#CTQ~pY4 z7ONd*(R~4PdOHVSkIYB*Pc=GMfY3baPFHYj%}2-&k5uY8wB+S7xSUu10%8EHrINIX z?$V%(ORFc-CN}n)`;K*bw{3AEyX@Js2lWU+kw3@=#*~fx+BAu99cLOd5F?MG zHf-D|tl)UWF8WyLCW{RlHe3`Cvpje(6-%NNzFikR1F{+Lx#>S?vA)Q^D(q4Fh4=6X@Tj$J~>~yG4J&Ahs#3&IIwgIdqRwsO! z+C;Gm#|bRz>({TnjhW76cjXWPSOiK3gM4(fyE@dut?ssznHqWf_U)h#y*RUddei4e zS|OCekIfIBJ$nY0bDmd#{w>T_jlBQ%#;)evX;6|+ld~zbE662&TSlJ4Yi#ybg!MvE z@7|QEqRcq8OG{bq#P^alg^>2{UUo@ z+b%~VNYpmkcdS0`lsXyrx@g7LjFC_K4fR}mYX|$%TcSX{XC{Y%+WO|imrslDcv-Xx z3k%fnzN#VWxrXUjsU!b*ezt4RHrxs_+}DJ5OS)eDnZtCXnj&mXjNsH7`4Ix1_?r;p8FZtUN* z{n#`f`Tpu5r@ch0XT2A}s7A&O@>5-UYq$JpOq@A=2*{lNtR7I>7VtevA>zg`xjx0J zc&MXPo&3VKA_>o8>TDT8V|uJFe2djy#MqS7jkn<5Hr+{@*xjnJt5>fYN}B*=P+~;s z6K&F6PX^YW1*0RW9)INaHgCE=o61Dh&N)?+#F%&`hN3-x;V+xfVW`Zs34o_LRKkbqVV246gSyJ9u!b&%^-kjiQFKt_z+(P-!D0-Kd@0eVv|C z3a8mD#(0xE_nSOxyUTZdyRYChc|A$lbWoI7QPDmrOPm!yZ*qO^gq_SAj$}7_^(02K zLqtpMO!O8YP*xe{F-3`k(Jz2EA)^g6Bw|GXH&`J60JS`$?c&OB@52aq4rL&-hsCMJKU9lRYHot($&>uA#al z@RrIEpMAyUG;>61t+1lfbC1CkJ^w{|Vx0chSM-w&YK$nhLTDMyBRAt~@mROW> zjkqu7U2-dsh)F@^3=w@>QPJ|kR`2A=uC_`PN%uF)ZFi10IzwVHva#tPcpO#&Iq1-| z7mi(3^?J`U1D=S`&`{Bn=;p`}%w`5oUf%sh2q>C=Zf?cS;rD3BQ1v6|Q(YjEPsT=Z zoNC-ooW0n1TzO`_v@|XC#DO$vg7YV+_!-I%MatUhcDLaka8>9)XJ7mJ=_&T5QVO9c1&ew@ zbyOqk+}#>KwifuMI?C&ao}IYwQ=gv>wij1G3;-iXl?I2^R8j;XJ^01asc30kU7djP z#1XstCifO4hvpn~lV3YKji+xAkKlkH?{juz<_j8&epN`Cp9=9SXr=s_Pmi?XW2eU1 zD)@X=c==tq9I8@jsE!FB2(H~eg`y`_9I^hG?+D}DzT6*x9ri%OF1uTW7x7IB-1R3| zV;lY~Q~%2<_kV!NVPJfus}H2z+{<04qu+p>d1_Y@+26?E_j&V0{ZR z31A{5Wm<(YARg0KpY{X{H(cI98B+p6{zI-1oUw(=8GmAW=E2@&7?BKI9?`Tnp7mE1 zLsR~>Bp8`S104hdJ9@NjYP1KZpZyqy?Dqh_i)L^pp`_%ZyF>cTLba#$^&nOK^aZ{B zLZxZVpoJjV$|E1tD-Y|knHugciiO6PBYq9 zw#5C8<(Z`N($f7wsSYj5OnpmB`a~*Lc99aJ9rhgZc9kXs3@(SwC0J>7-Wpstj^peH zML~`1FZQMp;7%!o8o(cIWNNxX?QrJV4(?0^_hx7)7q?tdUM?zUSLMylH69%k6f@G- z*Y6Xk)+ zK0SJC6KXM5=0JA_8{Z$gDbZ{Ct$<)Ya7<_Y`t=GAlx1>P=f!mkv{v;6LQ@JAt;=w- zBDY;K<6(?Gp)I0DU<jX2`#0aj;*Rkj~+#X6qq3} zU}772OLNV)^2l&ePiR4Ep*~^$D^sThW^YH`^-ykUoNYBHF6p$coni_{!8sXd$@t|uU=@HK5CeN+4 zs?BuQ*jX1K2ck8Ds@$p>~$nUP%XwtUo-8j zNF*Uu!V3Udrg$S#_z+k0?=pFfb$WNVp2Q`cx+5GEM!C31hT^(=l{43BJqmImZk@;tw%GS6A2T(T_@<@M#qj~_qW8!*MPN=`aOM-*L=e^L20i*6 zf_c>END2Twg!KbVbwjGZtRf=qIR5@iX%x?mB{6iz?SbmcneWwLhDk zGc{1CrkEn(3Whogwj1qrP3iz zI-n7v&2}4u54crzWOc6~k*-s{9=&|RQOZXlCWKMUW8MUbF#zkzQ{NwgutPS}?5+b! z=VCYqE`i%yZs0xIeJEgj!nFkVb^TXjJvJ>W|A&X~pfxI>V1&;x{JtTiDltGLw@@o!rm0ji5cvVe1?#@tzFQ6eTj zekE%m5T`k~0K1gDMldKo-JCP|tt{Lu{Y);#fp{gh#UAM@zV{lLnhKW=rW!v{wIdXq z(Ec8hl0P8Mhuxpp{UdwT?+J+RR5<&!1j!_Ak(G*p)U#)fumr&!!}Eu6n+W^!UOYgq4hBMiT;E+@%dVP$}eKE2mi~((xkPHZ|fzS#d zAyAp%pcd{;uG8ae8Y;zKwSt~*TU{$q5;>{ovbVM+HSmMmE!d_XMBaxv}TsMwsytfr4JS$q5=!I{C>#%OvU@NQM&l!MhFQ`36P5D42AC@+;s6hDYZ=usfc)wNX; zBTUSWFzu3}q45z0@d(t6PQ`Fqt#$dPr zGr#GTfGHe?`1>V7Fx+J??g}4DXU+Bvn5`GdG-o&gp=EZ13CK;%HvAR5Z$(C0STu~x zMO<57A;gxt@d^RqKd_wBunI@zZ_)fm`|1AYh}eIxFYwR%_-D~|)!hICncTl9#7v6t z1Ui5phZUqt|2;;nq!L^*@EcED^^D4#L&J*1e}e{_q3Lv=$svf22aSxjIW+qqZ(y3R zgmj8mPdqN8t;{2HgH)?$0*U`sZp#(_G6g>(A;4gY|LO65Xax{dYm#XyAe-7hDnq;3 z8;)NJ&I_b~tzqoGzv#Yz2uSZwjFXe%;!4WOlvl-fE z1RqatO>zqa8+9_|V=(1#!n(2yy+Zz=)bO}d^WOqfWF1<9>t|tjg)c81DuZ+6j^&C+ zDEI1Zl(8}exA)=l$uQNyPKcVtfd7cFp=u|S@6}uPZqp=PU;NhkIlMope2|~QEct}5 zqADt3jJdR&cv^= z5e8_uh*jO)&ijksdXSA_cy^RKBb@u;f5FF@gb76B+Ak?+!SJB9llf)X15>k~)AN=_ zNRxzvV4TSxOpc5Dp4F3tPN^AVWAr1j+F?JdeXo1biCBX^$g=iwb=1y)pO!zF*2zaI zUJEryfz#wtsgs;DwC{%lv*5RR@WQIYuEa08a{^9`(~TJ^7*ViUTsl-1*<9_CJFx72 z!{}xfy(bi|xRF+3@2e)~z|fq9suGC>@e&r=i5k>SqVf09A>SRlw!6LAc8juD$ygp!4 z+m#qt59mon?O7h>WMU8^lRKXjX99}mgXi4O;&MQTLT}z|bSf6XoWc{W69y_1L#5IJ zzid7N7aYu&cA#5uq{`$TF7ZRfbZE*-+jDgpJ7>83ma%0WIvYI5wxsO-cW>Wj!ZWIi z>Q5+waO(@g?2!V)@jBQ(RWRYlbYIMpg(>={GKjAT zwAd&wyT%MB?AE)HeN-#uL7#K@jIE80PMC}h;tBJ-_ak0B$}4#ms_t%PaA%3J4TwN4 zoKOa%-VnExU>lDYVd<&Nj$p19y3ynl_?LF_5}9_?bYIxLY7))d-~AfPq~PaVFgbfT z$VTNKLMI;Ssd0db1LSdk86gEDzg|3lE|X>Fr&qc?pS1fCT0u~)V%EEIn-41CMN-Yh-vwsa6{3HSvEZ6RvcXKen1EtGW zSf+pVhq?S;E!7ZnVf^UDJB7@j2yekuys@R{+A!^xcGVlsm!5x5c;aC}EDDN}zMjwm zI|)?8s^AJRupG3g0wO!Mf*WZkuV}42i=B4T5}S;;b;}jrmL?eW;s@cbWI=AYy!#mJ ztdOZIdRJ51`BiB5u1ra7*g)7MVuVV$HO);IwpJJO2y-7E{G{rvdFQ@Ku#{Ff-%941 z#o2M|YxoS*_DCprFV3b&O2>Exi(gsmnqt07Kfv^8!Tc@p8z0U)&X;|CHF@v*lt;p! z6F%;&DDtdrudKXUpl(~?oEKfn-7dsh>D1!P=@cdz7A-qL^1HI8r>1B0u6E4W*cdeM z1=Km`^5M6A)%L8RFKUa`#Wh;u;^OAw7w@i(7P?30nTaM?$5PBaA=_IfyCWR}0s^is zliILp6QWQ4mxXGVii5<2goMPDytc~A%foZ~q`Lm}%gdL4dK^3dW}91fPj@$6pM_F| zzaEfdh?6+#wJ^Wwrxg_JO0GGzb%ms)HPC1;Foo%tn z*wr;H=gXi+LPElC1+DN^g~Sdv3B?&crxV!)ZyFFD`J0)S*UTP|-s$=2SW4~bZI5mL z;ulS{+!VD-nrm)^hntz1^|Zq{f?h<{~tt+G? zB}3em-QC=F2=m8QX4+PWPR5lTKV@&f$p00F1@Fp#BB{KQ#Ws?uuk-W$)@a$=+lL7G zDo0b)nrD9HaGFB(*DnbwW^g0?R-;I+Sh;d~YDz{{Hd40}mHEb~B=bYh=;ht3h502F zs3dLTZ$pGlA9w%${nXTh$u(D5tm$=9Qi^xZZ#;r$Mam*;q`f!@ zmS-(JJ#GR$Wc=K%s1*}UUpw2@(Kh_7hQ0UL83hOK{u?83d>!5x^TCBQAV`dZ8Ci~P zAp0*1j@(i5cC)Z(!u!0uyskT%a7?`dKUpjWm-2O2qE&{?s#y zRJF+QNTGZ|OH5dJMMW`^390CuK1wp+F}ue@ns|9)>(u$FTWd~QTQhq~^raGwBx@XK zv=-=^vNAHj5%hx31=s14sYXu^Z&6n6AN2Sda=u^{J7Dhh1sPEI^WE$E++Nhp9GZR8 zK3HB}4yWAi)xjn&juXD$%*^dl0jJ*S$3w-OoaG2fTau}wJ3aIb4GqoB0cA6E#^ztD z?9xKq4W4<=@q0euum~rVlanL7XPiC`o&%;1W{IESE{6q<3;MS$JTWcpP?r`@(UN7$ zpup~>OT%kf1peXg@6U$C4x)g=XX%y?^Y5+dCw510$oI%(dUnyVuKs?vO!MmM>Y)Qc z#fFCtEnPUjqv93GZn*80|Du)Ka=bq5Z7PqS;(ZQjh~zLRk79FNwG`ucha=_wy& z>TWtcPezs}{wO#l=)jetV{X}zQ}eDrC$c>z;od#M3g5Gy?}FN*MT?*Uc;#AVX8PT{ z9u}5~A~!hb)Geg??ie4OkE|moH^G`;;g0so#UDoumz9+X3JOA{{?z5NFKGTFW=hJI z^98E2b2N2`FlHTbaY>DdiAhhFU$@TI#ii=VX7gMx*S5k7`zq!=y8f0O@Q}{)XbDF3 zel&3{0|tZp;luThCpJn;8+!?_ay`Hz87v}3I(`h=50LorX(E(~-@uP%WhFk!x9YLu z4{A!fx1f;+S__7IbBKdrs+dQZ03Ze|AQl6`dFc=D7RhhJk4BJ0I`l&tgmprd=y^$` igXak8@}GKwiMfT_7Hbup<$p$8SZj~&?j*G%zx@lMc)Ak+ literal 19107 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 Yv0QybXYG)|ub(L&P*aSRH@x=00FKepQ2+n{ From 955b755d389fb1f91692b3eb5686245bba0b2882 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:06:51 +0530 Subject: [PATCH 2/6] Updated performance results in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e2359711..bf982ab9 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ Get started with the benchmarks: | Server | Requests/sec | Latency (ms) | |--------|--------------|--------------| -| apollo | 0 | 16.896666666666665 | -| tailcall | 0 | 602.0966666666667 | +| apollo | 0 | 0 | +| tailcall | 0 | 702.3133333333334 | ### Throughput (Higher is better) From 9e1700b3e3a5fe9caf89bda530c9634655aa2f01 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:40:25 +0530 Subject: [PATCH 3/6] Updated performance results in README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index bf982ab9..ce736c98 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ Get started with the benchmarks: | Server | Requests/sec | Latency (ms) | |--------|--------------|--------------| -| apollo | 0 | 0 | -| tailcall | 0 | 702.3133333333334 | +| apollo | 6539.554307143364 | 15.292914015494107 | +| tailcall | 115357.753852638 | 0.8600929656600531 | ### Throughput (Higher is better) From 439e1d370f06e7b752b8e18848ca446c80c7db20 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:55:13 +0530 Subject: [PATCH 4/6] Updated performance results in README.md --- README.md | 4 ++-- assets/latency_histogram.png | Bin 16132 -> 14677 bytes assets/req_sec_histogram.png | Bin 14231 -> 15521 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce736c98..142b9a5f 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ Get started with the benchmarks: | Server | Requests/sec | Latency (ms) | |--------|--------------|--------------| -| apollo | 6539.554307143364 | 15.292914015494107 | -| tailcall | 115357.753852638 | 0.8600929656600531 | +| apollo | 7035.942102917875 | 14.21787901160235 | +| tailcall | 112556.64979546318 | 0.8808227626467039 | ### Throughput (Higher is better) diff --git a/assets/latency_histogram.png b/assets/latency_histogram.png index bf9d20884635374f0399c3c3f9732a654c852b58..c45a7f5daf22fb68d7c5d7850e617abfd442b4b1 100644 GIT binary patch literal 14677 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 N9alUSOF4JrKLCGRkyro# literal 16132 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 diff --git a/assets/req_sec_histogram.png b/assets/req_sec_histogram.png index 1ee873dd014ba310f781726a16b86c32bc5932c4..4f486f2f96803cbb1591a97dc7795a5a04b10cbc 100644 GIT binary patch literal 15521 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 bVDs|!jjSKlQ-f)nAP(%&Qje#fzWo0H9h6NH literal 14231 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 From 10e5df4aee39088d1a9752ebaf0a014a016500f4 Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:57:30 +0530 Subject: [PATCH 5/6] Updated performance results in README.md --- README.md | 4 ++-- assets/latency_histogram.png | Bin 14677 -> 14675 bytes assets/req_sec_histogram.png | Bin 15521 -> 16292 bytes 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 142b9a5f..83653a77 100644 --- a/README.md +++ b/README.md @@ -44,8 +44,8 @@ Get started with the benchmarks: | Server | Requests/sec | Latency (ms) | |--------|--------------|--------------| -| apollo | 7035.942102917875 | 14.21787901160235 | -| tailcall | 112556.64979546318 | 0.8808227626467039 | +| apollo | 6543.885258627874 | 15.464760673819313 | +| tailcall | 121400.78711951857 | 0.8161994372989355 | ### Throughput (Higher is better) diff --git a/assets/latency_histogram.png b/assets/latency_histogram.png index c45a7f5daf22fb68d7c5d7850e617abfd442b4b1..f7ebca6162f4feae708e7360639c3da5c4f93f96 100644 GIT binary patch literal 14675 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 literal 14677 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 N9alUSOF4JrKLCGRkyro# diff --git a/assets/req_sec_histogram.png b/assets/req_sec_histogram.png index 4f486f2f96803cbb1591a97dc7795a5a04b10cbc..784faafd1ae65cbd827ed8c9dc5c4df71ae6faf6 100644 GIT binary patch literal 16292 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 bVDs|!jjSKlQ-f)nAP(%&Qje#fzWo0H9h6NH From 31141bc7b3a410e9adf08d5f4ebfc4f6ddee9d2e Mon Sep 17 00:00:00 2001 From: neo773 <62795688+neo773@users.noreply.github.com> Date: Tue, 2 Jul 2024 15:58:21 +0530 Subject: [PATCH 6/6] fix scripts, rewrite to js --- analyze.js | 129 +++++++++++++++++++++++++++++ analyze.sh | 107 ------------------------ generate_load.sh | 11 +++ graphql/tailcall/benchmark.graphql | 16 +--- graphql/tailcall/run.sh | 2 +- run_benchmarks.sh | 26 +++--- setup.sh | 4 +- wrk/apollo_bench.sh | 1 - wrk/dgs_bench.sh | 1 - wrk/gqlgen_bench.sh | 1 - wrk/tc_bench.sh | 1 - wrk/wrk.lua | 5 -- 12 files changed, 161 insertions(+), 143 deletions(-) create mode 100644 analyze.js delete mode 100755 analyze.sh create mode 100644 generate_load.sh delete mode 100755 wrk/apollo_bench.sh delete mode 100755 wrk/dgs_bench.sh delete mode 100755 wrk/gqlgen_bench.sh delete mode 100755 wrk/tc_bench.sh delete mode 100644 wrk/wrk.lua diff --git a/analyze.js b/analyze.js new file mode 100644 index 00000000..9476ac1e --- /dev/null +++ b/analyze.js @@ -0,0 +1,129 @@ +#!/usr/bin/env node + +const fs = require("fs"); +const { execSync } = require("child_process"); + +const average = (arr) => arr.reduce((a, b) => a + b, 0) / arr.length; + +const servers = ["apollo", "netflixdgs", "gqlgen", "tailcall"]; + +const resultFiles = process.argv + .slice(2) + .filter((arg) => arg.startsWith("result") && fs.existsSync(arg)); + +const extractMetrics = (files) => { + return files.map((file) => { + const { summary } = JSON.parse(fs.readFileSync(file, "utf8")); + return { + requestsPerSec: summary.requestsPerSec, + latency: summary.average * 1000, + }; + }); +}; + +const calculateAverages = (metrics) => { + return servers.reduce((acc, server, index) => { + const serverMetrics = metrics.slice(index * 3, (index + 1) * 3); + acc[server] = { + avgReqSec: average(serverMetrics.map((m) => m.requestsPerSec)), + avgLatency: average(serverMetrics.map((m) => m.latency)), + }; + return acc; + }, {}); +}; + +const writeDataFile = (filename, data) => { + fs.writeFileSync(filename, "Server Value\n"); + Object.entries(data).forEach(([server, value]) => { + fs.appendFileSync(filename, `${server} ${value}\n`); + }); +}; + +const generateGnuplotScript = (reqSecData, latencyData) => ` +set term pngcairo size 1280,720 enhanced font "Courier,12" +set style data histograms +set style histogram cluster gap 1 +set style fill solid border -1 +set xtics rotate by -45 +set boxwidth 0.9 +set key outside right top + +set output "req_sec_histogram.png" +set title "Requests/Sec" +stats "${reqSecData}" using 2 nooutput +set yrange [0:*] +plot "${reqSecData}" using 2:xtic(1) title "Req/Sec" + +set output "latency_histogram.png" +set title "Latency (in ms)" +stats "${latencyData}" using 2 nooutput +set yrange [0:*] +plot "${latencyData}" using 2:xtic(1) title "Latency" +`; + +const generateResultsTable = (averages) => { + let table = + "\n| Server | Requests/sec | Latency (ms) |\n|--------|--------------|--------------|"; + Object.entries(averages).forEach(([server, { avgReqSec, avgLatency }]) => { + table += `\n| ${server} | ${avgReqSec} | ${avgLatency} |`; + }); + return table + "\n"; +}; + +const updateReadme = (resultsTable) => { + const readmePath = "README.md"; + let content = fs.readFileSync(readmePath, "utf8"); + const regex = + /[\s\S]*/; + content = content.includes("PERFORMANCE_RESULTS_START") + ? content.replace(regex, resultsTable) + : content + "\n\n" + resultsTable; + fs.writeFileSync(readmePath, content); +}; + +const main = () => { + const metrics = extractMetrics(resultFiles); + const averages = calculateAverages(metrics); + + resultFiles.forEach(fs.unlinkSync); + + const reqSecData = "/tmp/reqSec.dat"; + const latencyData = "/tmp/latency.dat"; + + writeDataFile( + reqSecData, + Object.fromEntries( + Object.entries(averages).map(([k, v]) => [k, v.avgReqSec]) + ) + ); + writeDataFile( + latencyData, + Object.fromEntries( + Object.entries(averages).map(([k, v]) => [k, v.avgLatency]) + ) + ); + + const gnuplotScript = generateGnuplotScript(reqSecData, latencyData); + fs.writeFileSync("/tmp/gnuplot_script", gnuplotScript); + execSync("gnuplot /tmp/gnuplot_script"); + + if (!fs.existsSync("assets")) fs.mkdirSync("assets"); + ["req_sec_histogram.png", "latency_histogram.png"].forEach((file) => + fs.renameSync(file, `assets/${file}`) + ); + + const resultsTable = generateResultsTable(averages); + updateReadme(resultsTable); + + console.log(resultsTable.replace(/\n?/g, "")); + + execSync( + "git add README.md assets/req_sec_histogram.png assets/latency_histogram.png" + ); + execSync('git commit -m "Updated performance results in README.md"'); + execSync("git push"); + + resultFiles.forEach(fs.unlinkSync); +}; + +main(); diff --git a/analyze.sh b/analyze.sh deleted file mode 100755 index a9aee262..00000000 --- a/analyze.sh +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/bash - -function extractMetric() { - local file="$1" - local metric="$2" - grep "$metric" "$file" | awk '{print $2}' | sed 's/ms//' -} - -function average() { - echo "$@" | awk '{for(i=1;i<=NF;i++) s+=$i; print s/NF}' -} - -servers=("apollo" "netflixdgs" "gqlgen" "tailcall") -resultFiles=("$@") -declare -A avgReqSecs -declare -A avgLatencies - -# Extract metrics and calculate averages -for idx in "${!servers[@]}"; do - startIdx=$((idx * 3)) - reqSecVals=() - latencyVals=() - for j in 0 1 2; do - fileIdx=$((startIdx + j)) - reqSecVals+=($(extractMetric "${resultFiles[$fileIdx]}" "Requests/sec")) - latencyVals+=($(extractMetric "${resultFiles[$fileIdx]}" "Latency")) - done - avgReqSecs[${servers[$idx]}]=$(average "${reqSecVals[@]}") - avgLatencies[${servers[$idx]}]=$(average "${latencyVals[@]}") -done - -# Generating data files for gnuplot -reqSecData="/tmp/reqSec.dat" -latencyData="/tmp/latency.dat" - -echo "Server Value" > "$reqSecData" -for server in "${servers[@]}"; do - echo "$server ${avgReqSecs[$server]}" >> "$reqSecData" -done - -echo "Server Value" > "$latencyData" -for server in "${servers[@]}"; do - echo "$server ${avgLatencies[$server]}" >> "$latencyData" -done - -# Plotting using gnuplot -gnuplot <<- EOF - set term pngcairo size 1280,720 enhanced font "Courier,12" - set output "req_sec_histogram.png" - set style data histograms - set style histogram cluster gap 1 - set style fill solid border -1 - set xtics rotate by -45 - set boxwidth 0.9 - set title "Requests/Sec" - stats "$reqSecData" using 2 nooutput - set yrange [0:STATS_max*1.2] - set key outside right top - plot "$reqSecData" using 2:xtic(1) title "Req/Sec" - - set output "latency_histogram.png" - set title "Latency (in ms)" - stats "$latencyData" using 2 nooutput - set yrange [0:STATS_max*1.2] - plot "$latencyData" using 2:xtic(1) title "Latency" -EOF - - -# Move PNGs to assets -mkdir -p assets -mv req_sec_histogram.png assets/ -mv latency_histogram.png assets/ - -# Generating the table results for README.md -resultsTable="\n| Server | Requests/sec | Latency (ms) |\n|--------|--------------|--------------|" - -for server in "${servers[@]}"; do - resultsTable+="\n| $server | ${avgReqSecs[$server]} | ${avgLatencies[$server]} |" -done - -resultsTable+="\n" - -# Check if the markers are present -if grep -q "PERFORMANCE_RESULTS_START" README.md; then - # Replace the old results with the new results - sed -i "/PERFORMANCE_RESULTS_START/,/PERFORMANCE_RESULTS_END/c\\$resultsTable" README.md -else - # Append the results at the end of the README.md file - echo -e "\n$resultsTable" >> README.md -fi - -# Print the results as a table in the terminal -echo -e $resultsTable | sed "s///;s///" - -# Move the generated images to the assets folder -mv req_sec_histogram.png assets/ -mv latency_histogram.png assets/ - -# Add and commit changes -git add README.md assets/req_sec_histogram.png assets/latency_histogram.png -git commit -m "Updated performance results in README.md" -git push - -# Delete the result TXT files -for file in "${resultFiles[@]}"; do - rm "$file" -done diff --git a/generate_load.sh b/generate_load.sh new file mode 100644 index 00000000..be689361 --- /dev/null +++ b/generate_load.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +PORT=$1 + +oha -z 10s -c 100 -m POST \ + -H "Connection: keep-alive" \ + -H "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" \ + -H "Content-Type: application/json" \ + -d '{"operationName":null,"variables":{},"query":"{posts{title}}"}' \ + --json \ + http://localhost:$PORT/graphql \ No newline at end of file diff --git a/graphql/tailcall/benchmark.graphql b/graphql/tailcall/benchmark.graphql index 6de8e1ab..6cc71047 100644 --- a/graphql/tailcall/benchmark.graphql +++ b/graphql/tailcall/benchmark.graphql @@ -1,16 +1,11 @@ schema - @server( - port: 8083 - baseURL: "http://jsonplaceholder.typicode.com" - enableHttpCache: false - enableGraphiql: "/graphiql" - proxy: {url: "http://localhost:3000"} - ) { + @server(port: 8083) + @upstream(baseURL: "http://jsonplaceholder.typicode.com") { query: Query } type Query { - posts: [Post] @http(path: "/posts") + users: [User] @http(path: "/users") } type User { @@ -18,14 +13,11 @@ type User { name: String! username: String! email: String! - phone: String - website: String + posts: [Post] @http(path: "/users/{{.value.id}}/posts") } type Post { id: Int! - userId: Int! title: String! body: String! - user: User @http(path: "/users/{{value.userId}}") } diff --git a/graphql/tailcall/run.sh b/graphql/tailcall/run.sh index 446e683b..abda7a47 100755 --- a/graphql/tailcall/run.sh +++ b/graphql/tailcall/run.sh @@ -1,3 +1,3 @@ #!/bin/bash current_dir=$(pwd) -$HOME/.tailcall/bin/tc start $current_dir/graphql/tailcall/benchmark.graphql \ No newline at end of file +$HOME/.tailcall/bin/tailcall start $current_dir/graphql/tailcall/benchmark.graphql \ No newline at end of file diff --git a/run_benchmarks.sh b/run_benchmarks.sh index fc6a2c04..0b25c39c 100755 --- a/run_benchmarks.sh +++ b/run_benchmarks.sh @@ -18,42 +18,42 @@ sh nginx/run.sh function runBenchmark() { local serviceScript="$1" - local benchmarkScript="$2" + local port="$2" # Replace / with _ local sanitizedServiceScriptName=$(echo "$serviceScript" | tr '/' '_') - local resultFiles=("result1_${sanitizedServiceScriptName}.txt" "result2_${sanitizedServiceScriptName}.txt" "result3_${sanitizedServiceScriptName}.txt") + local resultFiles=("result1_${sanitizedServiceScriptName}.json" "result2_${sanitizedServiceScriptName}.json" "result3_${sanitizedServiceScriptName}.json") bash "$serviceScript" & # Run in daemon mode sleep 15 # Give some time for the service to start up # Warmup run - bash "$benchmarkScript" > /dev/null + bash "./generate_load.sh" "$port" > /dev/null # 3 benchmark runs for resultFile in "${resultFiles[@]}"; do - bash "$benchmarkScript" > "$resultFile" + bash "./generate_load.sh" "$port" > "$resultFile" allResults+=("$resultFile") done } -runBenchmark "graphql/apollo_server/run.sh" "wrk/apollo_bench.sh" +runBenchmark "graphql/apollo_server/run.sh" 8080 cd graphql/apollo_server/ npm stop cd ../../ -killServerOnPort 8082 -runBenchmark "graphql/netflix_dgs/run.sh" "wrk/dgs_bench.sh" -killServerOnPort 8082 +# killServerOnPort 8082 +# runBenchmark "graphql/netflix_dgs/run.sh" 8082 +# killServerOnPort 8082 -killServerOnPort 8081 -runBenchmark "graphql/gqlgen/run.sh" "wrk/gqlgen_bench.sh" -killServerOnPort 8081 +# killServerOnPort 8081 +# runBenchmark "graphql/gqlgen/run.sh" 8081 +# killServerOnPort 8081 killServerOnPort 8083 -runBenchmark "graphql/tailcall/run.sh" "wrk/tc_bench.sh" +runBenchmark "graphql/tailcall/run.sh" 8083 killServerOnPort 8083 # Now, analyze all results together -bash analyze.sh "${allResults[@]}" \ No newline at end of file +node analyze.js "${allResults[@]}" diff --git a/setup.sh b/setup.sh index 71f2027a..1e732fec 100755 --- a/setup.sh +++ b/setup.sh @@ -15,5 +15,7 @@ cd graphql/netflix_dgs cd ../../ # For tailcall: -curl -sSL https://raw.githubusercontent.com/tailcallhq/tailcall/main/install.sh | bash -s -- v0.10.0 +curl -sSL https://raw.githubusercontent.com/tailcallhq/tailcall/main/install.sh | bash -s export PATH=$PATH:/root/.tailcall/bin + +cargo install oha diff --git a/wrk/apollo_bench.sh b/wrk/apollo_bench.sh deleted file mode 100755 index 55023f5c..00000000 --- a/wrk/apollo_bench.sh +++ /dev/null @@ -1 +0,0 @@ -wrk -d 10 -t 4 -c 100 -s $(pwd)/wrk/wrk.lua http://localhost:8080/graphql diff --git a/wrk/dgs_bench.sh b/wrk/dgs_bench.sh deleted file mode 100755 index 4cd8e419..00000000 --- a/wrk/dgs_bench.sh +++ /dev/null @@ -1 +0,0 @@ -wrk -d 10 -t 4 -c 100 -s $(pwd)/wrk/wrk.lua http://localhost:8082/graphql diff --git a/wrk/gqlgen_bench.sh b/wrk/gqlgen_bench.sh deleted file mode 100755 index f95c2437..00000000 --- a/wrk/gqlgen_bench.sh +++ /dev/null @@ -1 +0,0 @@ -wrk -d 10 -t 4 -c 100 -s $(pwd)/wrk/wrk.lua http://localhost:8081/graphql diff --git a/wrk/tc_bench.sh b/wrk/tc_bench.sh deleted file mode 100755 index a7224afd..00000000 --- a/wrk/tc_bench.sh +++ /dev/null @@ -1 +0,0 @@ -wrk -d 10 -t 4 -c 100 -s $(pwd)/wrk/wrk.lua http://localhost:8083/graphql diff --git a/wrk/wrk.lua b/wrk/wrk.lua deleted file mode 100644 index d87bd060..00000000 --- a/wrk/wrk.lua +++ /dev/null @@ -1,5 +0,0 @@ -wrk.method = "POST" -wrk.body = '{"operationName":null,"variables":{},"query":"{posts{title}}"}' -wrk.headers["Connection"] = "keep-alive" -wrk.headers["User-Agent"] = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36" -wrk.headers["Content-Type"] = "application/json"