<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: karthick-கார்த்திக்</title>
    <description>The latest articles on Forem by karthick-கார்த்திக் (@ehrktia).</description>
    <link>https://forem.com/ehrktia</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F996232%2F15078cd0-2aba-409d-81d1-0d3f6eb24255.png</url>
      <title>Forem: karthick-கார்த்திக்</title>
      <link>https://forem.com/ehrktia</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/ehrktia"/>
    <language>en</language>
    <item>
      <title>Postgres vs Redis</title>
      <dc:creator>karthick-கார்த்திக்</dc:creator>
      <pubDate>Mon, 26 Dec 2022 22:15:04 +0000</pubDate>
      <link>https://forem.com/ehrktia/postgres-vs-redis-579m</link>
      <guid>https://forem.com/ehrktia/postgres-vs-redis-579m</guid>
      <description>&lt;h3&gt;
  
  
  Why ?
&lt;/h3&gt;

&lt;p&gt;ℹ️ Recent article from &lt;a href="https://www.amazingcto.com/postgres-for-everything" rel="noopener noreferrer"&gt;ycombinator&lt;/a&gt; provides an idea about using postgres as a one stop shop for all data related needs for the application , quoting from the article&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use Postgres for caching instead of Redis with UNLOGGED tables and TEXT as a JSON data type.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;thought for this experiment originated from above quote&lt;/p&gt;

&lt;h3&gt;
  
  
  Objective
&lt;/h3&gt;

&lt;p&gt;Compare query execution time between postgres unlogged table and redis using API layer built in Golang&lt;/p&gt;

&lt;h3&gt;
  
  
  Procedure
&lt;/h3&gt;

&lt;p&gt;For readers who are interested in codified version of the &lt;br&gt;
experiment can checkout the &lt;a href="https://github.com/web-alytics/performance-stat" rel="noopener noreferrer"&gt;repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;steps&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;set up required data stores (postgres and redis)&lt;/li&gt;
&lt;li&gt;create an API layer in Golang for store interaction&lt;/li&gt;
&lt;li&gt;set up query performance measurement tools for stores&lt;/li&gt;
&lt;li&gt;run benchmark and operations on store&lt;/li&gt;
&lt;li&gt;collect and compare&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;pre-requisites&lt;/strong&gt;&lt;br&gt;
 &lt;br&gt;
Thanks to &lt;a href="https://hub.docker.com/search?q=postgres" rel="noopener noreferrer"&gt;docker&lt;/a&gt;, Both stores can be set up using official docker images available from docker hub.Below are queries used to set up the containers&lt;br&gt;
&lt;code&gt;pg_stat_statements&lt;/code&gt; extension can be used to monitor query performance as far as redis is concerned the inbuilt &lt;code&gt;redis-benchmark&lt;/code&gt; can be used from the command line&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

docker run -d --name postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-p 5432:5432 \
-v `pwd`/docker/init.sql:/docker-entrypoint-initdb.d/init.sql \
postgres:latest -c shared_preload_libraries='pg_stat_statements'


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Above docker command can help to start postgres instance up and ready&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/web-alytics/performance-stat/blob/main/docker/init.sql" rel="noopener noreferrer"&gt;init.sql&lt;/a&gt; contains basic setup for the database code associated with experiment&lt;/p&gt;

&lt;p&gt;once after the server is ready and working either pgadmin or psql can be used to interact with it&lt;br&gt;
&lt;a href="https://github.com/web-alytics/performance-stat/blob/main/docker/init_table.sql" rel="noopener noreferrer"&gt;init_table.sql&lt;/a&gt; holds the required statements for creation of a table and extension&lt;/p&gt;

&lt;p&gt;redis setup is more straightforward&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

docker run -d --name redis -p 6379:6379 redis:latest


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;approach&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;naive and simple approach is being adopted for the purpose of experiment&lt;br&gt;
One line summary of the approach is to build an API layer in golang and measure query statistics using golang's in-built benchmarking and testing&lt;/p&gt;

&lt;p&gt;Code for API layer is available in &lt;a href="https://github.com/web-alytics/performance-stat" rel="noopener noreferrer"&gt;repo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;how it works - There are isolated adapters set up for both stores, All required operations for populating data into store and reading required data are carried using go test&lt;/p&gt;

&lt;p&gt;Benchmark for get opeartion(postgres) and put(redis) are used to get query stats for the corresponding store&lt;/p&gt;

&lt;p&gt;To execute store operation - &lt;code&gt;go test -run ./... -tags=integration&lt;/code&gt; which sets up required data in the stores &lt;/p&gt;

&lt;p&gt;To measure performance of query a quick load test is carried out using the benchmark functions in test, to get load test and benchmark&lt;/p&gt;

&lt;p&gt;postgres API query latency benchmark can be observed using &lt;/p&gt;

&lt;p&gt;&lt;code&gt;go test -bench . ./adapter/store/pgsql -count 10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in similar manner redis benchmark can be calculated using &lt;br&gt;
&lt;code&gt;go test -bench . ./adapter/store/redis -count 10&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;postgres query performance can be monitored via &lt;code&gt;pg_stat_statements&lt;/code&gt; extension using the SQL query&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;

&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;total_exec_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;min_exec_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;max_exec_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;mean_exec_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pg_stat_statements&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'select * from public.test'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;redis bench mark can be observed using inbuilt tool for redis&lt;/p&gt;

&lt;p&gt;&lt;code&gt;redis-benchmark -h localhost -p 6379 -n 10000&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Query latency from both data layer and API layer can be measured using extensions and benchmark&lt;/p&gt;

&lt;h3&gt;
  
  
  observation
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;max exec time&lt;/th&gt;
&lt;th&gt;db&lt;/th&gt;
&lt;th&gt;no of rows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.013056668&lt;/td&gt;
&lt;td&gt;postgres-unlogged&lt;/td&gt;
&lt;td&gt;27570000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.029535&lt;/td&gt;
&lt;td&gt;redis&lt;/td&gt;
&lt;td&gt;27570000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nydsdhdzk55kl78ac2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1nydsdhdzk55kl78ac2h.png" alt="pg vs redis"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  conclusion
&lt;/h3&gt;

&lt;p&gt;From original artical covering multiple aspects of postgres followed by the naive experiment between pg and redis.It is clearly evident and this acts as additional proof postgres can be one stop shop for all data related needs for any application &lt;/p&gt;

&lt;h3&gt;
  
  
  Bibiliography
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://hub.docker.com/search?q=" rel="noopener noreferrer"&gt;dockerhub&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hub.docker.com/_/postgres" rel="noopener noreferrer"&gt;postgres&lt;/a&gt;&lt;br&gt;
&lt;a href="https://redis.io/docs/management/optimization/benchmarks/" rel="noopener noreferrer"&gt;redis&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Some Self promotion&lt;/p&gt;

&lt;p&gt;&lt;a href="https://twitter.com/ehrktia" rel="noopener noreferrer"&gt;twitter&lt;/a&gt;, &lt;a href="//@karthie@mastodon.social"&gt;mastodon&lt;/a&gt;, &lt;a href="https://github.com/ehrktia" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>postgres</category>
      <category>redis</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
