<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title></title>
      <link>https://www.madewithtea.com</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://www.madewithtea.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Tue, 04 Mar 2025 00:00:00 +0000</lastBuildDate>
      <item>
          <title>End of Alcohol</title>
          <pubDate>Tue, 04 Mar 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/end-of-alcohol/</link>
          <guid>https://www.madewithtea.com/posts/end-of-alcohol/</guid>
          <description xml:base="https://www.madewithtea.com/posts/end-of-alcohol/">&lt;p&gt;Most days we live on autopilot, programmed by habits defined by us or others. Drinking alcoholic drinks is a habit that most people acquire at a young age. It may be deeply ingrained over decades, forming a part of our identity. It takes awareness to stop reacting and question&#x2F;interrogate this part. I argue it&#x27;s worth it since it blocks us from our ideal life.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-sound-mind-in-a-healthy-body&quot;&gt;A sound mind in a healthy body&lt;&#x2F;h2&gt;
&lt;p&gt;My definition of an ideal life includes a sound mind in a healthy body. A sound mind means no brain fog, no sluggishness, less self-deception but clarity and awareness. In my view, it&#x27;s the foundation for making optimal decisions and to experience life to the fullest. Shifting the view to a healthy body: there is a staggering amount of research findings that discuss alcohol significantly impacting physical health, we get into that.&lt;&#x2F;p&gt;
&lt;p&gt;I started my journey in August 2023 as a self-experiment, and after a few setbacks, I am proud to have been abstinent for more than a year. The pride faded, and I adopted a new normal. This text serves as self-reflection and aims to inspire others to re-evaluate&#x2F;challenge their long-held beliefs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consistent-small-wins&quot;&gt;Consistent small wins&lt;&#x2F;h2&gt;
&lt;p&gt;While a transition to an ideal life is a long one, it starts with small consistent compounding changes and &quot;small wins&quot; to practice every day. To stop drinking for a week, a month, or for the entire next month to then revise if one wants to keep to it. With enough momentum and lessons learned, it can be easier to overcome setbacks and quit drinking alcohol completely. Before I outline the ugly effects on health, I&#x27;d like to start with the commonly believed &quot;benefits&quot; of drinking alcohol and dismantle them by perspective shift. And finally, if you&#x27;re convinced I hope my takeaways at the end will support you in your journey.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;social-default-relaxation-and-coping&quot;&gt;Social default, relaxation and coping&lt;&#x2F;h2&gt;
&lt;p&gt;The reason most of us started drinking alcohol is social interaction. The reason we stick to it is mostly social default (cultural norms, norms of a group or institutional influence) or as a coping mechanism.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s start with social default. The need for belonging is hard-wired in humans. It is said that the shared consumption of alcoholic beverages brings people together (&quot;social glue&quot;) and loosens their tongues (&quot;truth potion&quot;, “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;In_vino_veritas?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;in vino veritas&lt;&#x2F;a&gt;”). It is said that people become more bold, fearless, have more style, and can better enjoy themselves. Decades of aggressive marketing has reinforced it.&lt;&#x2F;p&gt;
&lt;p&gt;From a sober person&#x27;s perspective, a drunk person is often said to speak their mind, but they also tend to have loose lips, bad manners, bad smell, and make poor decisions that can lead to regrettable actions, malicious behavior, cheating, and even accidental harm to others - in fact, alcohol is a factor in 40% of violent crimes. The morning after, the hangover and its accompanying mood swings can put an extra strain on relationships with friends, partners, or family.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not saying it&#x27;s easy to say ‘no’ in social settings. Years after stopping, my parents still ask me if I’d like to have a drink. In a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;drchatterjee.com&#x2F;blog&#x2F;why-wait-for-dry-january-heres-why-the-right-time-for-a-break-from-alcohol-is-now&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;poll&lt;&#x2F;a&gt; in 2019, 97% of respondents said they felt social pressure to drink, and 85% felt that pressure at work too. I&#x27;m saying let&#x27;s make drinking optional. It is a social default but it doesn&#x27;t have to be. If your group doesn&#x27;t tolerate your new behavior it&#x27;s probably a good idea to re-evaluate the group&#x27;s shared values or find a new one.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s briefly touch on alcohol as a coping mechanism. In a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.mintel.com&#x2F;app&#x2F;smush-webp&#x2F;2024&#x2F;01&#x2F;UK-Reasons-Drinking-Alcohol-1024x709.png.webp?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;2023 poll&lt;&#x2F;a&gt; in the UK, “to relax”, and “to treat myself” have been cited by 60% and 50% of consumers. Red wine is said to make you forget. Alcohol among other drugs is the easy way out to cope with anxiety, stress, depression and loss. Many of us have learned this behavior when growing up. It&#x27;s a short-term fix but not a real solution. The worst part: whenever you&#x27;re faced with one or a combination of the above you don&#x27;t learn&#x2F;grow to deal with it (through healthy means such as running and meditation) and&#x2F;or process it. Furthermore, a vicious self reinforcing cycle can develop in which coping with alcohol can increase stress and anxiety in the long run. Now, if you aren’t convinced yet, let’s look into the real ugly side of alcohol.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;alcohol-destroys-the-body-and-the-brain&quot;&gt;Alcohol destroys the Body and the Brain&lt;&#x2F;h2&gt;
&lt;p&gt;The hangover the morning after is just the tip of the iceberg. Alcohol increases blood pressure and dehydrates the body (bad skin). It decreases &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nature.com&#x2F;articles&#x2F;s41467-022-28735-5?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;gray and white matter in the brain&lt;&#x2F;a&gt;, weakens your immune system and prevents healing. It has negative effects on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;time.com&#x2F;7210400&#x2F;why-is-alcohol-unhealthy&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;digestion and gut microbiomes&lt;&#x2F;a&gt; leading to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hopkinsmedicine.org&#x2F;health&#x2F;conditions-and-diseases&#x2F;gastritis?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;gastritis&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nature.com&#x2F;articles&#x2F;tp201715?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;leaky gut syndrome&lt;&#x2F;a&gt;. Excessive alcohol consumption can cause nerve damage and irreversible forms of dementia. Alcohol raises &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.acc.org&#x2F;About-ACC&#x2F;Press-Releases&#x2F;2024&#x2F;03&#x2F;28&#x2F;11&#x2F;58&#x2F;alcohol-raises-heart-disease-risk-particularly-among-women?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;heart disease risk&lt;&#x2F;a&gt; even &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pubmed.ncbi.nlm.nih.gov&#x2F;39363568&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;for young adults&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Long-term alcohol abuse can lead to permanent and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;my.clevelandclinic.org&#x2F;health&#x2F;diseases&#x2F;15572-cirrhosis-of-the-liver?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;irreversible scarring in your liver&lt;&#x2F;a&gt;. Moreover, alcohol is classified as a Group 1 carcinogen, meaning it is proven to cause cancer. In fact, any amount of alcohol consumption increases your risk of developing &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.cancer.gov&#x2F;about-cancer&#x2F;causes-prevention&#x2F;risk&#x2F;alcohol&#x2F;alcohol-fact-sheet?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;six types of cancer&lt;&#x2F;a&gt;: head and neck cancer, esophagus cancer, liver cancer, breast cancer, and colon and rectum cancer.  Fortunately, the World Health Organization is pushing to have &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.who.int&#x2F;europe&#x2F;news-room&#x2F;14-02-2025-alcohol-labels-should-warn-of-cancer-risk--says-new-who-europe-report?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;warning labels on alcoholic beverages&lt;&#x2F;a&gt; to alert consumers to these cancer risks. A more complete in-depth summary is provided by Andrew Huberman’s episode “&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hubermanlab.com&#x2F;episode&#x2F;what-alcohol-does-to-your-body-brain-health?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;What Alcohol Does to Your Body, Brain &amp;amp; Health&lt;&#x2F;a&gt;”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;aha-moments&quot;&gt;Aha Moments&lt;&#x2F;h2&gt;
&lt;p&gt;My most important learning is to commit to stop entirely, because exceptions can become a rule with enough social pressure or life circumstances. What helps is to commit to a certain period such as 90 days to get into a new mindset, identify with a person who doesn&#x27;t drink alcohol. And make it a rule not an opinion. I can&#x27;t put it better than Shane Parrish from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.penguinrandomhouse.com&#x2F;books&#x2F;611709&#x2F;clear-thinking-by-shane-parrish&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Clear Thinking&lt;&#x2F;a&gt;: &quot;In a quirk of psychology, people typically don&#x27;t argue with your personal rules. They just accept them as features of who you are. People question decisions, but they respect rules.&quot;. A good book on habit formation is James Clear’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jamesclear.com&#x2F;atomic-habits?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Atomic Habits&lt;&#x2F;a&gt;. For the first 3 months, I employed a habit tracker, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.stridesapp.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Strides&lt;&#x2F;a&gt;, to keep track of good and bad days. This helped to have an overview of progress and for keeping myself accountable.&lt;&#x2F;p&gt;
&lt;p&gt;Shifting the focus on health, I barely have brain fog or headaches, much better sleep and with it more clarity, energy and less mood swings. I have much better skin (less dehydration and inflammation). While I don’t have personal before&#x2F;after data from my tracking devices, the Oura ring data shows a community trend of +8% impact of &quot;No Alcohol&quot; on Heart Rate Variability (HRV, higher is better) among users.&lt;&#x2F;p&gt;
&lt;p&gt;It became easier for me to approach people without alcohol. I have more deeper, authentic, honest and intellectually challenging conversations than I would have under the influence of alcohol. I can dance, sing and do whatever I do with alcohol but without it. Some situations remain challenging, I recall a wedding celebration of a friend, getting forcefully dragged onto the dance floor. Water is usually not served in wine glasses being the odd one out not clinking glasses. Every sober discomfort is a re-learning to approach situations anew.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s talk supply. Once I stepped outside the matrix, I was astonished how much alcohol is sold in supermarkets. Germany&#x27;s alcohol-free &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.dw.com&#x2F;en&#x2F;is-germanys-drinking-passion-waning&#x2F;a-71326039?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;beers are decent&lt;&#x2F;a&gt;, but note that alcohol percentages vary from 0.5% to 0%. Alcohol-free white wine (Prosecco) is similar in taste, red wine not so much. Apart from alcohol-free versions the world has plenty of non-alcoholic beverages to explore. A healthy alternative that I’ve learned to love is Kombucha. It’s fermented tea with a complex tangy flavor that is also a great probiotic to support gut health.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;&#x2F;h2&gt;
&lt;p&gt;You might have cut back on alcohol, stopped drinking or succeeded only for a period to then return to your status quo. It’s important to acknowledge our struggles without judgment. Instead of fighting our inner demons, such as being too strict to ourselves, we can learn to understand and befriend them by understanding where the desire is coming from. In the beginning of this text, I outlined my why: a sound mind in a healthy body. Maybe we share this one - or maybe you have more concrete reasons and stories to remind you and to give you a refreshed conviction to stay on this path - until there’s no path but a new normal. I want to conclude this text with Confucius’ words: “You can overcome bad habits only today, not tomorrow”.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;EDIT: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=aOwmt39L2IQ&amp;amp;pp=ygUSa3Vyemdlc2FndCBhbGNvaG9s0gcJCfwJAYcqIYzv&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Kurzgesagt animation about Alcohol&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pubmed.ncbi.nlm.nih.gov&#x2F;39363568&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Acute alcohol consumption and arrhythmias in young adults: the MunichBREW II study&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;An episode that has inspired me among other resources to take the leap is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hubermanlab.com&#x2F;episode&#x2F;what-alcohol-does-to-your-body-brain-health?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;What Alcohol Does to Your Body, Brain &amp;amp; Health&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=M3x_o5MBXb4&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Glucose Revolution - How Alcohol Impacts your Body and Brain&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nature.com&#x2F;articles&#x2F;s41467-022-28735-5?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Associations between alcohol consumption and gray and white matter volumes in the UK Biobank&lt;&#x2F;a&gt; (&lt;em&gt;Nature Communications&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.mdpi.com&#x2F;2077-0383&#x2F;10&#x2F;3&#x2F;541?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Gut Microbiota at the Intersection of Alcohol, Brain, and the Liver&lt;&#x2F;a&gt; (&lt;em&gt;Journal of Clinical Medicine&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;pubmed.ncbi.nlm.nih.gov&#x2F;38289182&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Why Do Only Some Cohort Studies Find Health Beneﬁts From Low-Volume Alcohol Use? A Systematic Review and Meta-Analysis of Study Characteristics That May Bias Mortality Risk Estimates&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;abs&#x2F;pii&#x2F;S009130572100054X?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Tolerance to alcohol: A critical yet understudied factor in alcohol addiction&lt;&#x2F;a&gt; (&lt;em&gt;Pharmacology Biochemistry and Behavior&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;onlinelibrary.wiley.com&#x2F;doi&#x2F;10.1111&#x2F;acer.14147?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Associations Between Drinking and Cortical Thickness in Younger Adult Drinkers: Findings From the Human Connectome Project&lt;&#x2F;a&gt; (&lt;em&gt;Alcoholism: Clinical and Experimental Research&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.nejm.org&#x2F;doi&#x2F;10.1056&#x2F;NEJM198705073161902?url_ver=Z39.88-2003%F0%9D%94%AFid%3Dori%3Arid%3Acrossref.org%F0%9D%94%AFdat%3Dcr_pub++0pubmed&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Moderate Alcohol Consumption and the Risk of Breast Cancer&lt;&#x2F;a&gt; (&lt;em&gt;The New England Journal of Medicine&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sciencedirect.com&#x2F;science&#x2F;article&#x2F;abs&#x2F;pii&#x2F;S0741832900001245?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Can alcohol promote aromatization of androgens to estrogens? A review&lt;&#x2F;a&gt; (&lt;em&gt;Alcohol&lt;&#x2F;em&gt;)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;michaeldavis.xyz&#x2F;2024-06-04&#x2F;alcohol-free-life-how-i-gave-up-booze-and-found-clarity&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=end-of-alcohol&quot;&gt;Living Sober: How Quitting Alcohol Changed My Life&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Investing into Drosera&#x27;s Seed Round</title>
          <pubDate>Tue, 11 Feb 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/leading-drosera-seed-round/</link>
          <guid>https://www.madewithtea.com/posts/leading-drosera-seed-round/</guid>
          <description xml:base="https://www.madewithtea.com/posts/leading-drosera-seed-round/">&lt;p&gt;The original publication can be found at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;greenfield.xyz&#x2F;2025&#x2F;02&#x2F;10&#x2F;backing-drosera-the-immune-system-for-ethereum&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=leading-drosera-seed-round&quot;&gt;Greenfield Publications&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We at Greenfield are excited to lead Drosera’s $3.25M seed round with participation of Anagram, Arrington Capital, Paper Ventures, UDHC and Pulsar. This funding will be instrumental in further developing and deploying Drosera’s innovative decentralized incident detection and response solution to ensure the safety of onchain value. The team has an exceptional track record in relevant fields such as cybersecurity&#x2F;malware analysis at the US Army Cyber Command, DeFi and MEV at Franklin Templeton, BitGo, Obol and Composable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;attacks-and-failures-in-defi&quot;&gt;Attacks and failures in DeFi&lt;&#x2F;h2&gt;
&lt;p&gt;DeFi grew increasingly complex from 2020 onwards. The risk of economic attacks has been historically underestimated, leading to many cases of exploitation using a combination of economically interdependent protocols. Categories like flash loan attacks (Euler | $197M), price oracle manipulation (Mango markets | $117M), bridge related attacks (Wormhole Hack | resulted in $320M of WeETH not being backed) have emerged. Liquid staking tokens (LSTs), liquid restaking tokens (LRTs) and yield-bearing stablecoins (through, e.g., treasuries) have further increased complexity with staking (custom lockup and redemption), restaking (to stake the same asset multiple times), and dependence on (opaque) offchain yield.&lt;&#x2F;p&gt;
&lt;p&gt;The risks of LSTs and LRTs are heightened due to complex factors that can lead to de-pegging. LRTs inherit the de-pegging risks of LSTs and add their own. This was evident in mid-2022 when stETH, typically pegged 1:1 to ETH, deviated significantly in price due to market fears following the Terra&#x2F;Luna collapse, leading to cascading liquidations in DeFi lending. Shifting focus from LSTs&#x2F;LRTs to stable coins, recently, Usual Money’s USD0++, a staked version of the USD0 stablecoin, updated its redemption policy without prior notice, causing a sell-off that dropped its price to $0.93 and impacted protocols using USD0++. Mispriced economic value in staking can further affect network security in proof-of-stake systems. Another example is Circle’s USDC de-pegging in 2023, driven by macroeconomic factors like inflation and interest rates. USDC fell to $0.88 after it was revealed that $9.7B of its reserves were at Silicon Valley Bank, which was facing a bank run. This led to a loss of over $6B in supply as investors feared a crash.&lt;&#x2F;p&gt;
&lt;p&gt;A joint report from the European Banking Authority (EBA) and the European Securities and Markets Authority (ESMA) has summarised known risks of DeFi and recommended the introduction of disaster recovery and incident response mechanisms (2.4&#x2F;95).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;drosera&quot;&gt;Drosera&lt;&#x2F;h2&gt;
&lt;p&gt;Drosera builds the immune system for Ethereum and its surrounding EVM ecosystem. It offers a unique solution by enabling the self-service creation of “traps” to detect and respond to potential threats and failures, as outlined above.&lt;&#x2F;p&gt;
&lt;p&gt;Traps can be fine-tuned, activated or deactivated without a redeployment of a smart contract. The traps are defined by protocol developers or trappers (auditors and economic auditors) using Solidity code, targeting EVM-based ecosystems, incorporating both objective, verifiable facts, using zero-knowledge proofs, and subjective assessments, e.g. anomaly detection or proprietary models. The resulting incident response task for a trap is taken care of by adequately incentivized operators (and block builders). Incentivization and market forces ensure a required top-of-block execution to avert exploitation or failure. It is paramount to decentralize its operation over designing incident response in a centralized manner leading to single point of failure and corruption risk.&lt;&#x2F;p&gt;
&lt;p&gt;The network has already made considerable progress, with more than 25 protocols, including Ion Protocol, EtherFi, and Gravita, committed to its Testnet. Additionally, it has established partnerships with various node operators like Infstones, Everstake, Cosmostation, a41, and Blockscape, and joined forces with security specialist GoPlus.&lt;&#x2F;p&gt;
&lt;p&gt;We are excited about the experienced team and its relentless drive to redefine onchain security. In DeFi, economic audits and bug bounties are simply not enough. Drosera provides the crucial building block of holistic real-time threat detection and incentivized response.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Leading Arcium&#x27;s Strategic Round</title>
          <pubDate>Thu, 09 May 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/investing-into-arcium/</link>
          <guid>https://www.madewithtea.com/posts/investing-into-arcium/</guid>
          <description xml:base="https://www.madewithtea.com/posts/investing-into-arcium/">&lt;p&gt;The original publication can be found at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;greenfield.xyz&#x2F;2024&#x2F;05&#x2F;09&#x2F;backing-arcium&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Greenfield Publications&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;We at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;greenfield.xyz&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Greenfield&lt;&#x2F;a&gt; are excited to lead Arcium’s $5.5M strategic funding round to launch the first parallelized confidential computing network. Other investors include Coinbase Ventures, Heartcore Capital, LongHash VC, L2 Iterative Ventures, Staking Facilities, Smape Capital and Everstake along with angel investors including &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;anatoly-yakovenko?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Anatoly Yakovenko&lt;&#x2F;a&gt;, co-founder of Solana, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;posts&#x2F;keone-hon_monad-raises-19m-to-build-the-fundamentally-activity-7031380502594932736-kAxD?trk=public_profile_like_view&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Keone Han&lt;&#x2F;a&gt;, co-founder of Monad, Mert Mumtaz, co-founder of Helius Labs, Santiago R Santos, Kenny Li, co-founder of Manta Network and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;lucasbruder?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Lucas Bruder&lt;&#x2F;a&gt;, co-founder of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.jito.network&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Jito&lt;&#x2F;a&gt; amongst others.&lt;&#x2F;p&gt;
&lt;p&gt;Arcium was founded by &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;de.linkedin.com&#x2F;in&#x2F;yannik-schrade?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Yannik Schrade&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;de.linkedin.com&#x2F;in&#x2F;juliandeschler?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Julian Deschler&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;de.linkedin.com&#x2F;in&#x2F;nicolas-schapeler?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Nicolas Schapeler&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.linkedin.com&#x2F;in&#x2F;lukas-ste&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;Lukas Steiner&lt;&#x2F;a&gt;. They have already impressed us with Elusiv, their previous project, pioneering user-friendly and compliant &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;greenfield.xyz&#x2F;2023&#x2F;11&#x2F;22&#x2F;reviving-transaction-privacy&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=investing-into-arcium&quot;&gt;transaction privacy&lt;&#x2F;a&gt; on Solana. Now with Arcium the team builds a foundational technology that unlocks a plethora of existing and new use cases, that require confidentiality, for Web3.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;privacy-is-everywhere&quot;&gt;Privacy is everywhere&lt;&#x2F;h2&gt;
&lt;p&gt;Privacy is a fundamental human right and a core element of our daily lives. Examples where privacy matters can be found easily: payments, bank transactions, medical records, messaging, voting and legal contracts. Privacy is not only normal – but a prerequisite for exercising freedom of thought&#x2F;speech and as a consequence essential for democracy. Anonymity and&#x2F;or confidentiality are the two core components of privacy. Whereas anonymity ensures the identity of the user is unknown, confidentiality ensures the user’s action&#x2F;information is unknown. To understand the pressing need for confidentiality within Web3 let’s first juxtapose it to Web2:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-old-world&quot;&gt;The old world&lt;&#x2F;h2&gt;
&lt;p&gt;In Web2, surveillance capitalism is a prevalent business model. The product seems to be free, but the hidden cost is the user’s information. The user gives up on anonymity and confidentiality toward the service company, but remains optionally anonymous&#x2F;confidential toward other users. Collected information is stored in private silos and used in a variety of company-benefitting use cases: 1) to optimize the user’s timeline in such a way that the user spends more time on the platform 2) to target adequate customers with optimal advertisements (remember Cambridge Analytica) 3) to resell user information to the highest bidder for diverse downstream use cases e.g. training data for AI models, predictive policing, voter trend analysis and more. Hence, companies have a strong incentive to acquire more and to reinforce the information asymmetry by e.g., closing previously available APIs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-new-world&quot;&gt;The new world&lt;&#x2F;h2&gt;
&lt;p&gt;This is in stark contrast to Web3: Information is stored publicly on-chain to ensure integrity and to be able to verify the authenticity thereof, be it a financial transaction, a loan, a limit order, a social graph, or a digital twin deed. Public data and interface standards allow streamlined cooperation between protocols in a permissionless manner resulting in strong network effects. The public traces of these on-chain interactions are stored on an immutable ledger such as Ethereum or Solana for anybody to utilize. Hence, confidentiality as a feature of these systems does not exist. When assessing anonymity one can easily make the mistake that these systems are anonymous. While it’s true that wallets&#x2F;accounts can be created and used without sharing one’s identity, they can be easily linked to off-chain metadata such as IP or browser fingerprint and tracked across interactions with protocols&#x2F;exchanges, etc. Hence, most blockchains are pseudo-anonymous and non-confidential.&lt;&#x2F;p&gt;
&lt;p&gt;Enabling confidentiality in Web3 finally makes many existing use cases in Web2 (including information asymmetry) possible in Web3. The even more exciting use cases, however, will combine the old network effects of Web2 with the new network effects and capabilities of Web3: liveness, permissionlessness, composability, censorship resistance, verifiability, and, last but not least, ownership.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;technology&quot;&gt;Technology&lt;&#x2F;h2&gt;
&lt;p&gt;Arcium is revolutionizing secure computation on encrypted data with its innovative “Multi-Party eXecution Environments” (MXEs). By integrating technologies like multi-party computation (MPC), homomorphic encryption, zero-knowledge proofs, and more, MXEs provide a customizable and secure environment for confidential computing. The team strives to have a frictionless developer experience providing adequate tooling and support.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Cold Shower Therapy and Ritual</title>
          <pubDate>Thu, 07 Mar 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/cold-shower-therapy-and-ritual/</link>
          <guid>https://www.madewithtea.com/posts/cold-shower-therapy-and-ritual/</guid>
          <description xml:base="https://www.madewithtea.com/posts/cold-shower-therapy-and-ritual/">&lt;p&gt;As probably most of my readers, I&#x27;ve heard of cold showers before. But I never seriously made an effort to deliberately shift to this discomforting practice... until last October. The rewarding effect of dopamine came right after the first shower- and for three months up to now, icy water has been my daily wake-up call. What began as a self-experiment has become a discomforting, but rewarding, morning ritual that gives mental clarity and ignites unforeseen energy levels for the day ahead. But what has originally convinced me to try it at least once?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;positive-effects-and-risks&quot;&gt;Positive effects and risks&lt;&#x2F;h2&gt;
&lt;p&gt;I heard that cold showers are good for the immune system but the most concise explanation I discovered was from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hubermanlab.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Andrew Huberman&lt;&#x2F;a&gt; on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=2XecbuI-9QE&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;this podcast&lt;&#x2F;a&gt;. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ncbi.nlm.nih.gov&#x2F;pmc&#x2F;articles&#x2F;PMC9518606&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Research studies&lt;&#x2F;a&gt; (added more below) have been performed using cold water submersion. The empirically found positive effects are mental clarity, feeling more energized in the morning and throughout the day, reduced inflammation, clearer skin, boosted metabolism, loosing weight, and improved mental resilience. Challenging yourself mentally every god damn morning makes the rest of the day feel like a piece of cake. And one more thing... Having this cold shock in the morning helps with clocking your &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sleepfoundation.org&#x2F;circadian-rhythm?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;circadian rhythm&lt;&#x2F;a&gt; and as a result with your overall sleep quality (no coffee needed). Just one little warning before going into specifics: After doing some research online for this article, I found &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.mayoclinic.org&#x2F;diseases-conditions&#x2F;cold-urticaria&#x2F;symptoms-causes&#x2F;syc-20371046?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;negative side-effects&lt;&#x2F;a&gt; might occur so please be careful and ask your doctor if symptoms occur.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;goal-setting-and-habit-formation&quot;&gt;Goal setting and habit formation&lt;&#x2F;h2&gt;
&lt;p&gt;Some online references recommend starting with a warm shower and gradually changing to a cold shower. I&#x27;ve done that in the past and it didn&#x27;t work for me, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=22167687&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;and others&lt;&#x2F;a&gt;. Seriously, I never dared to cool it down. Instead, this time I aimed to get rid of the warm shower option until I formed a strong habit of cold showers. For habit formation, I skimmed James Clear&#x27;s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jamesclear.com&#x2F;atomic-habits?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Atomic Habits&lt;&#x2F;a&gt; again and committed to the following system:&lt;&#x2F;p&gt;
&lt;p&gt;First, starting with a &quot;Why&quot;, which is all of the positive effects above. Second, a cue&#x2F;time&#x2F;place: every morning after waking up, go to the bathroom and start the routine. Next, decide on a duration and temperature. The minimum duration for this cold exposure is three minutes. The hardest part is the (needed) initial shock, so don&#x27;t worry about the duration. I went with the coolest setting coming out of the pipes- which after measuring turned out to be 7°C or 45°F. For me, this temperature is cold enough to trigger the desired physiological responses without being so cold as to cause me harm. The usual step for forming a habit is to define a reward for a dopamine spike afterward to wire the neurons. However, after stepping out of the discomfort the dopamine levels empirically increase 2.5x compared to the normal level. Hence, no other (external) rewards are needed. Last but not least, I recommend defining milestones like 7 days, 14 days, and 1 month to track progress. Streaks are important here because continuity overwrites habits. However, when you miss a day don&#x27;t be too hard on yourself and think about the overall success rate in the long run, e.g. 9 out of 10 days, while also chasing a new streak.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;before&quot;&gt;Before&lt;&#x2F;h2&gt;
&lt;p&gt;What has changed since I started having cold showers? I&#x27;ve been loyal to my cold showers most of the time. I seldom skipped the daily cold shower, and sometimes I did not take it directly after waking up. It became a morning ritual that has a big positive impact on my life. Why? Let me explain by contrasting the before and after. In the past it was hard for me to wake up, I felt sluggish throughout the morning. I usually crawled out of bed and procrastinated in the comfort of a warm blanket in bed and in the shower. What I never realized, is after waking up in a warm bed, and having a warm shower, any other sensation after just feels cold. Plus, I was still half asleep when stepping out of the shower, and only felt awake when the caffeine finally kicked in. On cold winter mornings, I shivered, wrapped in blankets, rubbing my back against the heater.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;with-cold-showers&quot;&gt;With Cold Showers&lt;&#x2F;h2&gt;
&lt;p&gt;Now, let&#x27;s visualize the alternative. I go to bed at 22:30 and wake up at 07:00 getting at least 8 hours of sleep. After, I go to the bathroom, brush my teeth, and step into the shower. At this moment, I consciously and unconsciously know that the early morning discomfort awaits, but I also know that I will feel unstoppable afterward. My heart rate climbs to 90. I put the timer on my shower radio for 3 minutes and start with cold watering my legs, arms, then my face and chest.  Relaxation is key, aim for long deep breaths. Now comes the best part: 10 minutes after getting up from bed, and right after getting out of the shower my energy level is peaking, my mind is clear and I feel unrestrained.&lt;&#x2F;p&gt;
&lt;p&gt;I think this is the perfect time to focus on the main goals in life, be it morning swimming, meditation, writing a book, sailing, surfing, learning the piano, or whatever &lt;em&gt;you&lt;&#x2F;em&gt; have in mind. I continue this practice because, as outlined, it had a huge positive impact on my life, and I share this story to maybe inspire you to at least try it once.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;extra-cold-and-warm-showers&quot;&gt;Extra: Cold and warm showers&lt;&#x2F;h2&gt;
&lt;p&gt;I didn&#x27;t have a warm shower for two months. I only had morning cold showers up to this point. I feared when having warm showers I would switch back immediately. So I decided to define a &lt;em&gt;different&lt;&#x2F;em&gt; why&#x2F;cue&#x2F;time for warm showers. Warm showers are a great way to relax, and relaxation is best for winding down to sleep. But instead of having warm showers every day, I take them as a reward for physical exercise, such as running, or as a cure against stress.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;research&quot;&gt;Research&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ncbi.nlm.nih.gov&#x2F;pmc&#x2F;articles&#x2F;PMC9518606&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Health effects of voluntary exposure to cold water – a continuing subject of debate, Sep 2022&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;377365991_Health_effects_of_cold_water_immersion_and_swimming_and_its_influence_on_the_human_body?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Health effects of cold water immersion and swimming and its influence on the human body, Jan 2024&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.researchgate.net&#x2F;publication&#x2F;375729802_Beyond_the_cold_baths_contemporary_applications_of_cold-water_immersion_in_the_treatment_of_clinical_depression_and_anxiety?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Beyond the cold baths: contemporary applications of cold-water immersion in the treatment of clinical depression and anxiety, Nov 2023&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;motivation-helpers&quot;&gt;Motivation helpers&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=6xpOD9SyksY&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Wim hof - No motivation to do cold showers?&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=7FlmpnsbciQ&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=cold-shower-therapy-and-ritual&quot;&gt;Wim hof - Wim Hof&#x27;s Top 10 reasons to take cold showers &amp;amp; ice baths&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Obsidian and (Local) LLMs</title>
          <pubDate>Fri, 22 Dec 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/obsidian-and-llms/</link>
          <guid>https://www.madewithtea.com/posts/obsidian-and-llms/</guid>
          <description xml:base="https://www.madewithtea.com/posts/obsidian-and-llms/">&lt;p&gt;In this post, I introduce &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;obsidian.md&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Obsidian&lt;&#x2F;a&gt;, compare it to Visual Studio Code, and highlight two notable LLM-powered Obsidian plugins namely &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;text-gen.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;TextGenerator&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;logancyang&#x2F;obsidian-copilot?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Copilot&lt;&#x2F;a&gt;. I follow on with their respective synergies, and the ability to use both of them with online-proprietary and local-open LLMs. I end with the prospect of more multi-modal Obsidian-shaped extendable interfaces to leverage LLMs.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;knowledge-tasks-in-obsidian&quot;&gt;Knowledge Tasks in Obsidian&lt;&#x2F;h2&gt;
&lt;p&gt;LLM-powered tooling improved the productivity of my day-to-day research. The task categories include understanding concepts faster, introspection of my writing&#x2F;thoughts, hardening arguments, brainstorming on options, extracting certain subjects for  in-depth analysis, and compressing information. For most of the above, I use &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;obsidian.md&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Obsidian&lt;&#x2F;a&gt; as my interface.&lt;&#x2F;p&gt;
&lt;p&gt;For the ones who haven&#x27;t heard of Obsidian yet: Obsidian is a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Personal_knowledge_management?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;personal knowledge management&lt;&#x2F;a&gt; (PKM) tool, some also call it a &#x27;second brain&#x27;. Obsidian allows the interlinking of notes which over time results in a graph of connected knowledge. The notes are plaintext files stored locally in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Markdown?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Markdown&lt;&#x2F;a&gt; format. This ensures continuity&#x2F;access to the data if you&#x27;re offline (for instance on a boat) or even without Obsidian. The interface is intuitive, and general enough that it allows for many different use cases. If you haven&#x27;t tried it yet, please take a stab at it- It&#x27;s free for personal usage. All in all, it&#x27;s a beautiful piece of software.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;open-extensions&quot;&gt;Open Extensions&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;code.visualstudio.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Visual Studio Code&lt;&#x2F;a&gt; has become the go-to IDE for many software developers and one important reason might be its vast &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;marketplace.visualstudio.com&#x2F;VSCode?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;extension library&lt;&#x2F;a&gt;, featuring among many more syntax extensions for the most obscure languages, integration with essential toolchains e.g. deployment, and code linting or manipulation. The latter has become surprisingly good with Github&#x27;s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;features&#x2F;copilot?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;CoPilot&lt;&#x2F;a&gt; or with plugins using OpenAI GPT-3&#x2F;4 in the background (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;chatgpt-codes&#x2F;blob&#x2F;main&#x2F;timeline&#x2F;src&#x2F;main.rs?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;experiment&lt;&#x2F;a&gt; last year).&lt;&#x2F;p&gt;
&lt;p&gt;Analogous to Visual Studio Code, Obsidian features extendability via &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;obsidian.md&#x2F;plugins?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Community Plugins&lt;&#x2F;a&gt;. The power&#x2F;flexibility that this gives to a code literate is unparalleled. There are many helpful plugins that I use on my day-to-day, however, here I&#x27;d like to focus on the LLM-powered plugins TextGenerator and Copilot (not to be confused with GitHub&#x27;s CoPilot) and use cases, such as the ones described at the beginning of the article.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;plugins-for-online-and-local-llms&quot;&gt;Plugins for Online and Local LLMs&lt;&#x2F;h2&gt;
&lt;p&gt;The first plugin, I tried is nhaouari&#x27;s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;text-gen.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;TextGenerator&lt;&#x2F;a&gt;. The most basic feature allows you to write prompts inline or select existing text to be evaluated as a prompt using various models. The plugin allows extendability with a prompt template system allowing users to create reusable prompts that can parse Markdown and Obsidian syntax, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.text-gen.com&#x2F;_notes&#x2F;Templates&#x2F;01+Understanding+Context?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;documentation&lt;&#x2F;a&gt;. If the underlying model supports it, it even allows multi-modal prompt input such as PDFs, audio, and images. Supported are proprietary models from &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;openai.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;OpenAI&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.anthropic.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Anthropic&lt;&#x2F;a&gt;, and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;deepmind.google&#x2F;technologies&#x2F;gemini&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Google&lt;&#x2F;a&gt; but also- and this is great for privacy, offline-first, and independence: TextGenerator features local open-source LLM integration with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ollama.ai&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Ollama&lt;&#x2F;a&gt;. Ollama is a user-friendly application to download and run open-source LLMs such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mistral.ai&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Mistral&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nousresearch.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Nous Research&lt;&#x2F;a&gt; Hermes and many others. And even better: you don&#x27;t even need a beefy GPU: e.g. Hermes 13B runs fast on a MacBook Pro M1 Pro.&lt;&#x2F;p&gt;
&lt;p&gt;The second plugin I want to highlight in this introductory post is Logan Yang&#x27;s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;logancyang&#x2F;obsidian-copilot?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;Obsidian Copilot&lt;&#x2F;a&gt;. One set up with OpenAI or local LLM backend, you have a chat side pane to prompt generally or to prompt specifically towards the current note. Compared to TextGenerator, this option is more suitable for on-demand prompting and prototyping of prompts&#x2F;questions. You can even save the chat log as a note to do further introspection. Therefore, using both in combination is ideal: first, determine the most effective approach and then create a reusable prompt template for TextGenerator.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The integration of LLM-powered extensions within open platforms such as Obsidian and Visual Studio Code represents a significant leap forward in how we manipulate information in natural language or code. Importantly, these new LLM enablers come in two different flavors: online-proprietary and local-open. While general proprietary LLMs are leading the general purpose benchmarks, the scores of open general LLMs caught up fast. Also- open LLMs allow for crowd-sourced fine-tuning and specialization, as seen on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;huggingface.co&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;HuggingFace&lt;&#x2F;a&gt;, which is similar to the extension&#x2F;plugin architecture of Obsidian and Visual Studio Code. I&#x27;m personally excited to see more extendable interfaces to make use of the coming plethora of (specialized) open LLMs.&lt;&#x2F;p&gt;
&lt;p&gt;To end with some ideas one could think of a collaborative&#x2F;multi-user photo-editing such as Photoshop or Gimp, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Digital_audio_workstation?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=obsidian-and-LLMs&quot;&gt;DAW&lt;&#x2F;a&gt; such as Ableton, a whiteboard such as Miro or Mural, or even a &quot;Blender&quot; (VR editing) that allows the easy creation of template prompts (for inserting, manipulating or commenting) based on online-proprietary or crowd-sourced local-open models.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Starting to Sail</title>
          <pubDate>Thu, 21 Sep 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/starting-to-sail/</link>
          <guid>https://www.madewithtea.com/posts/starting-to-sail/</guid>
          <description xml:base="https://www.madewithtea.com/posts/starting-to-sail/">&lt;p&gt;I spent my last summer sailing a lot in Berlin. Last autumn, I finally did my in-water license, after almost 25 years not sailing. Well as a small kid, without any formal education, I believe I didn&#x27;t know how sailings works. &#x27;Going back sailing&#x27; for me was one of those goals&#x2F;dreams that you don&#x27;t dare to realise because you fear it might not be what you expect.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reconnecting&quot;&gt;Reconnecting&lt;&#x2F;h2&gt;
&lt;p&gt;I remember well, on the first day of sailing school, the teacher familiarised us with the parts of a sailing boat. I sat in one, and while the boat was lifting up and down from the water, I realised this is going to be so much fun. The first time out on the water, we had strong winds, I enjoyed everything of it: the wind in the sails, feeling it pulling the lines, controlling the tiller and cutting our way through the water. I had great teachers and met interesting people in random groups on lots of weekends.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;being-in-nature&quot;&gt;Being in nature&lt;&#x2F;h2&gt;
&lt;p&gt;This year, after a long winter of not sailing, I started early getting back on the boat in April. It was around the time when birds just came back from the south. One early morning out on Wannsee, a group of hundreds of birds flew over us, and landed all around the boat. Like black dots on a silver plane. It was a magical moment. This year, I mostly sailed with family and friends in lakes around Berlin. And had my first experiences being on a sailing yachts in the Baltic Sea&#x2F;North Sea.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;continuation&quot;&gt;Continuation&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s almost the end of the year, hence I want to spend as much time on the water as possible. I also decided to continue learning with a costal water license, which includes learning how to navigate with compass, understand sea maps, pyro and the short radio certificate.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;m not sure where this journey will take me, but I love sailing I&#x27;m thanking my past self to have taken the leap.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Enablers and Catalysts in Lightning Network</title>
          <pubDate>Fri, 30 Jun 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/lightning-network/</link>
          <guid>https://www.madewithtea.com/posts/lightning-network/</guid>
          <description xml:base="https://www.madewithtea.com/posts/lightning-network/">&lt;p&gt;The original publication can be found at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;greenfield.xyz&#x2F;2023&#x2F;06&#x2F;30&#x2F;bitcoin_and_the_lightning_network&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Greenfield Publications&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bitcoin-a-different-category&quot;&gt;Bitcoin, a different category&lt;&#x2F;h2&gt;
&lt;p&gt;Bitcoin was created in the turmoil of the banking crisis in 2009. Satoshi inscribed the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.investopedia.com&#x2F;terms&#x2F;g&#x2F;genesis-block.asp?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;message&lt;&#x2F;a&gt; “The Times 03&#x2F;Jan&#x2F;2009 Chancellor on brink of second bailout for banks.” into the first block, referencing these turbulent times. Back then, the US bank Washington Mutual Bank failed with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bankrate.com&#x2F;banking&#x2F;largest-bank-failures&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;$307B in assets&lt;&#x2F;a&gt;. From then until now, 14 years later, we’re seeing US bank failures again with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bankrate.com&#x2F;banking&#x2F;largest-bank-failures&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Silicon Valley Bank with $209B&lt;&#x2F;a&gt; in assets. And the following failure of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bankrate.com&#x2F;banking&#x2F;largest-bank-failures&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Signature Bank with $110&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In the meantime, Bitcoin gained strength in an &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Antifragility?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;antifragile&lt;&#x2F;a&gt; manner from various regulatory attacks such as straight-out explicit bans e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.investopedia.com&#x2F;articles&#x2F;forex&#x2F;041515&#x2F;countries-where-bitcoin-legal-illegal.asp?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;China&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.investopedia.com&#x2F;articles&#x2F;forex&#x2F;041515&#x2F;countries-where-bitcoin-legal-illegal.asp?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Qatar&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.investopedia.com&#x2F;articles&#x2F;forex&#x2F;041515&#x2F;countries-where-bitcoin-legal-illegal.asp?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Saudi Arabia&lt;&#x2F;a&gt;, and various &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.investopedia.com&#x2F;articles&#x2F;forex&#x2F;041515&#x2F;countries-where-bitcoin-legal-illegal.asp?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;implicit bans&lt;&#x2F;a&gt;, to mining bans in e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reuters.com&#x2F;technology&#x2F;chinas-ban-forces-some-bitcoin-miners-flee-overseas-others-sell-out-2021-06-25&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;China&lt;&#x2F;a&gt;, to exchange bans, and technical attacks such as forking the chain, e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.investopedia.com&#x2F;tech&#x2F;history-bitcoin-hard-forks&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Bitcoin Cash in 2017&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.investopedia.com&#x2F;tech&#x2F;history-bitcoin-hard-forks&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;others&lt;&#x2F;a&gt;. This young asset has proven to be resilient over the last 14 years with a 100% uptime, a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitinfocharts.com&#x2F;en&#x2F;comparison&#x2F;bitcoin-hashrate.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network#3y&quot;&gt;higher hash rate&lt;&#x2F;a&gt; than ever before, countries adopting it as legal tender e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.reuters.com&#x2F;world&#x2F;americas&#x2F;el-salvador-approves-first-law-bitcoin-legal-tender-2021-06-09&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;El Salvador in 2021&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.bbc.com&#x2F;news&#x2F;world-africa-61248809?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Central African Republic in 2022&lt;&#x2F;a&gt;, and more and more people holding bitcoin for the long-term, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;app.santiment.net&#x2F;charts?settings=%7B%22slug%22%3A%22bitcoin%22%2C%22ticker%22%3A%22BTC%22%2C%22from%22%3A%222018-04-09T07%3A00%3A00.000Z%22%2C%22to%22%3A%222023-04-09T07%3A00%3A00.000Z%22%7D&amp;amp;widgets=%5B%7B%22widget%22%3A%22ChartWidget%22%2C%22wm%22%3A%5B%22price_usd%22%2C%22holders_distribution_total%22%5D%2C%22whm%22%3A%5B%5D%2C%22wax%22%3A%5B0%2C1%5D%2C%22wpax%22%3A%5B%5D%2C%22wc%22%3A%5B%22%2326C953%22%2C%22%23FF5B5B%22%5D%2C%22ws%22%3A%7B%220%22%3A%7B%22interval%22%3A%227d%22%2C%22node%22%3A%22candle%22%7D%7D%7D%5D&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Total Amount of Holders Chart&lt;&#x2F;a&gt;. With it came institutional adoption such as companies and funds taking Bitcoin &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcointreasuries.net&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;onto their balance sheet&lt;&#x2F;a&gt; e.g. MicroStrategy, Tesla, Block Inc. and many others. And just this month BlackRock filed for a spot Bitcoin ETF, and Fidelity is planning to do the same.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-interesting-advancements&quot;&gt;Some interesting advancements&lt;&#x2F;h2&gt;
&lt;p&gt;At Greenfield we&#x27;re excited about recent developments regarding &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcoinrollups.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;ZK rollups&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@RubenSomsen&#x2F;21-million-bitcoins-to-rule-all-sidechains-the-perpetual-one-way-peg-96cb2f8ac302?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;space chains&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;dci.mit.edu&#x2F;smart-contracts?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;discreet log contracts&lt;&#x2F;a&gt; (DLCs), &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.arkpill.me&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Ark&lt;&#x2F;a&gt;  and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fedimint.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Fedimint&lt;&#x2F;a&gt; – see Fig.2. A good way to stay updated with these advancements is the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcoinops.org&#x2F;en&#x2F;newsletters&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Bitcoin Optech newsletter&lt;&#x2F;a&gt;. One of the areas the team at Greenfield is particularly interested in is the Lightning Network (LN) and major advancements, like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.lightning.engineering&#x2F;the-lightning-network&#x2F;taproot-assets&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Taproot Assets&lt;&#x2F;a&gt;, among others, building on top of it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;lightning-network&quot;&gt;Lightning Network&lt;&#x2F;h2&gt;
&lt;p&gt;In 2015, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lightning.network&#x2F;lightning-network-paper.pdf?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Joseph Poon and Thaddeus Dryja&lt;&#x2F;a&gt; proposed the Bitcoin Lightning Network (LN): Scalable Off-Chain Instant Payments. This layer is built on top of Bitcoin to allow for instantaneous, private off-chain settlement in a decentralized way while leveraging Bitcoin’s security and asset. It is horizontally scalable since it’s not using a ledger, but rather a P2P network in which payments are routed. Instant settlement, low fees (&amp;lt;$0.01) and its privacy traits make it attractive for (micro) payments and for companies in the payment space to build on top of to compete with e.g. Visa and Mastercard, the world’s biggest payment processing networks. In a world of IoT and smart grids, the LN can be leveraged as a machine-to-machine payment system. For an analysis of its viability as a substitution for traditional global payment networks, I&#x27;d like to refer to Lyn Alden’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.lynalden.com&#x2F;lightning-network&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;A Look at the Lightning Network&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enablers-and-catalysts&quot;&gt;Enablers and catalysts&lt;&#x2F;h2&gt;
&lt;p&gt;In the period from the year 2015 of the inception of the idea until 2021, LN was only used by enthusiastic early adopters. The biggest obstacles were running an own Bitcoin full node, running a LN implementation, finding peers in the network to manually connect to and manually balancing lightning channels including &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;voltage.cloud&#x2F;blog&#x2F;bitcoin-lightning-network&#x2F;demystifying-inbound-liquidity&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;finding a source for inbound liquidity&lt;&#x2F;a&gt;. That’s a lot of friction considering almost nobody was accepting LN payments. With this in mind, let’s have a look at what has changed and led to the explosion of renewed interest in the LN:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Massive reduction of payment failure and an increase in connectivity:&lt;br &#x2F;&gt;
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;river.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;River Financial&lt;&#x2F;a&gt; states in its &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;blog.river.com&#x2F;insights-from-the-4th-largest-lightning-network-node&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;latest report&lt;&#x2F;a&gt; that in the early days of Lightning in 2018, due to limited liquidity needed for routing payments through channels, people had failed $5 transactions around ~48% of the time. In 2021 however, the network grew to 1,000 BTC of liquidity. By now, this has increased to even more than 5,500 BTC, a rough 5x growth within two years. River states that nowadays payment failure has dropped below 2%. Other growth metrics besides total channel capacity include channel count (but important to keep in mind channel quality over quantity) and. For total capacity and channel count, Coinmetric’s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;txstats.coinmetrics.io&#x2F;dashboard&#x2F;db&#x2F;lightning-network?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;dashboard&lt;&#x2F;a&gt; provides live data.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Advancements in UX and developer experience:&lt;br &#x2F;&gt;
On the user side next generation non-custodial wallets such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;phoenix.acinq.co&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Phoenix&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;breez.technology&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Breez&lt;&#x2F;a&gt; (also a PoS solution) allow for frictionless user onboarding to Lightning by leveraging &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcoin.design&#x2F;guide&#x2F;how-it-works&#x2F;lightning-services&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Lightning Service Providers&lt;&#x2F;a&gt; (LSPs) for both automatic and instant (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lightningdevkit.org&#x2F;blog&#x2F;zero-confirmation-channels&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;zero-confirmation&lt;&#x2F;a&gt;) LN channel opening. The fundamental problem of inbound liquidity to receive funds has only been partially solved however, see the challenges below. Custodial wallets, such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.walletofsatoshi.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Wallet of Satoshi&lt;&#x2F;a&gt; (predominantly used in El Salvador), and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cash.app&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;CashApp&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;strike.me&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Strike&lt;&#x2F;a&gt; are other important catalysts for the usability of LN (while the use of custodial wallets is debatable). On the developer side, SDKs such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcoindevkit.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;BDK&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;lightningdevkit.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;LDK&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;breez.technology&#x2F;sdk&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Breez SDK&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;rls.dev&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;River Financials’ API&lt;&#x2F;a&gt; accelerate the development of nodes, wallets, and services sending&#x2F;receiving lightning payments. Other UX improvements include new transaction types such as the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bolt12.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;BOLT12&lt;&#x2F;a&gt; offer type allowing users to receive (instead of sending) payments by scanning a QR code among others.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;
&lt;p&gt;Renewed interest in Bitcoin through experimentation and Taproot assets:&lt;br &#x2F;&gt;
This year the so-called &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.ordinals.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;Ordinal Theory&lt;&#x2F;a&gt; enabled the issuance of inscriptions (think of it as NFTs + on-chain content, more than &amp;gt;13M) on the Bitcoin base chain. It is a standard on how to interpret the existing blockchain data, without any modification, and attribute a new meaning off-chain to individually tracked on-chain satoshis. Another idea, the BRC-20 concept, leveraged inscriptions to enable fungible asset transactions on top of Bitcoin. Its market cap is by now &amp;gt;$100M. Both approaches are more of a hack, an experiment, rather than a serious proposal to extend Bitcoin but they proliferated new interest in Bitcoin. An upcoming and serious proposal to extend Bitcoin to support custom assets is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;coinshares.com&#x2F;research&#x2F;taro-a-new-asset-issuance-protocol-on-bitcoin?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network#key_takeaways&quot;&gt;Taproot Assets&lt;&#x2F;a&gt; (formerly known as Taro). These custom assets enable issuance on the Bitcoin blockchain and the use of them in  LN (while using the critical mass of liquidity of bitcoin locked in the network). A similar effort is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.rgbfaq.com&#x2F;what-is-rgb?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=lightning-network&quot;&gt;RGB&lt;&#x2F;a&gt;. Both enable centrally-issued stablecoins on Bitcoin and LN, which currently is a large chunk of liquidity settled on e.g. Ethereum. The ability to have stablecoins on Bitcoin&#x2F;LN is another controversial topic for the community.&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Bitcoin’s resilience, institutional adoption, and status as the most adopted cryptocurrency for payments and store of value make it a significant and differentiated player in the industry. The Lightning Network, built on top of Bitcoin, has emerged as a superior crypto payment system, offering horizontal scalability, low fees, and enhanced privacy. Recent developments in liquidity, connectivity, and user experience have fueled renewed interest and adoption of LN. However, challenges such as reliability, non-custodial scaling and easier ways to provide routing liquidity still need to be addressed.&lt;&#x2F;p&gt;
&lt;p&gt;Overall, Bitcoin’s unique attributes and the growth of the Lightning Network position them as transformative forces that might become, if challenges are accordingly addressed, in a couple of years time a viable alternative to upcoming centralized digital currency payment systems worldwide.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>From Scratch in Zola</title>
          <pubDate>Wed, 31 May 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/from-scratch-in-zola/</link>
          <guid>https://www.madewithtea.com/posts/from-scratch-in-zola/</guid>
          <description xml:base="https://www.madewithtea.com/posts/from-scratch-in-zola/">&lt;p&gt;The 10-year journey of static site generators led me to Ruby (Octopress), Python (Pelican) ultimately to Javascript (NextJS). Minimalism was always dear to my heart, but in this iteration of my site I practiced ultimate minimalism, not only in aesthetics but also for accessibility by low power, low bandwith devices.&lt;&#x2F;p&gt;
&lt;p&gt;When I started my blog in 2012 I used &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;octopress.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Octopress&lt;&#x2F;a&gt; (I was a Ruby fan back then, last release in 2015), then &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;getpelican.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Pelican&lt;&#x2F;a&gt; (Python) and ultimately &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;nextjs.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;NextJS&lt;&#x2F;a&gt; (Javascript) to generate my static website. NextJS is powerful, however, it&#x27;s too complex to add simple functionality such as RSS and Javascript library dependencies are just scary (security).  On top of that, I optimised the site for aesthetics using heavy fonts such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;fonts.google.com&#x2F;specimen&#x2F;Cardo?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Cardo&lt;&#x2F;a&gt; (~400kb from Google servers) and quiet complex layout that was hard to translate to mobile. It looked great on a Macbook, but accessibility via low power, low network bandwidth, devices was shit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;smol-web-permacomputing&quot;&gt;Smol web &amp;amp; Permacomputing&lt;&#x2F;h2&gt;
&lt;p&gt;You might ask why all of a sudden the change to become a smol&#x2F;handcraft web, no javascript enthusiast? I got inspired by the concept of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;permacomputing.net&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Permacomputing&lt;&#x2F;a&gt; and folks like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;0xff.nu&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;0xff&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;gav.space?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Gavin&lt;&#x2F;a&gt; who managed to pull off a beautiful, clean and functional site with few KBs. Other examples include XXIIVV&#x27;s &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;webring.xxiivv.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;webring site&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;250kb.club&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;250kb club&lt;&#x2F;a&gt; (madewithtea.com is less than 10kb now, without images), &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;emersion.fr&#x2F;blog&#x2F;2023&#x2F;status-update-53&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Emersion&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;max.dev&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Max&lt;&#x2F;a&gt; and the classic &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;motherfuckingwebsite.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Motherfuckingwebsite&lt;&#x2F;a&gt;. My made up requirements were modest: very simple CSS, dark mode, RSS feed, responsive design, no web font and of course markdown input.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-sharp-tool&quot;&gt;A sharp tool&lt;&#x2F;h2&gt;
&lt;p&gt;So I finally started this site from scratch again. And instead of building my own static site generator how all the cool kids are doing it (and what I initially planned to do, with the help of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kerkour.com&#x2F;rust-static-site-generator?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;kerkour&lt;&#x2F;a&gt;), I turned to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.getzola.org&#x2F;documentation&#x2F;getting-started&#x2F;overview&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=from-scratch-in-zola&quot;&gt;Zola&lt;&#x2F;a&gt;. Zola is a static site generator written in Rust and it&#x27;s basically just a binary. The documentation is clean and easy to grok. Just took me less than an hour to create a theme from nothing. It worked so well that I decided to write a piece about Zola. It just took me a few hours to set everything up, and will probably (hopefully) last for many years to come.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>The Multi-Chain Future</title>
          <pubDate>Wed, 30 Jun 2021 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/multi-chain-future/</link>
          <guid>https://www.madewithtea.com/posts/multi-chain-future/</guid>
          <description xml:base="https://www.madewithtea.com/posts/multi-chain-future/">&lt;p&gt;Different communities that form around blockchain projects view other projects in the crypto space primarily through the lens of competition and one-shot-winner-takes-all games. This is good because it drives innovation. However, it is shortsighted. In the long-term, the wider crypto ecosystem will thrive by experimentation, diversity and synergies. Hence, I argue that the future is multi- rather than single chain and should be viewed as a repeated, cooperative game. A multi-chain future with monetary value and trustless data flowing freely and inter-chain, would be more adaptable to changing conditions in the environment, more scalable, more resilient and naturally synergies would emerge. Let’s go through it one by one.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;adaptability&quot;&gt;Adaptability&lt;&#x2F;h2&gt;
&lt;p&gt;The whole is more adaptable. The decentralized instantiation of blockchain networks precedes test nets and waterfall-like phase gates. Design choices like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proof_of_work?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Proof-of-Work&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proof_of_stake?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Proof-of-Stake&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proof_of_space?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Proof-of-Space-Time&lt;&#x2F;a&gt; consensus are fundamental and can’t be easily changed after mainnet instantiation. This means that a single-chain future inhibits experimentation. In a multi-chain world, however, each blockchain can be its own one-shot experiment competing in a multivariate selection process driven by market forces.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;scalability&quot;&gt;Scalability&lt;&#x2F;h2&gt;
&lt;p&gt;The whole is more scalable, because in a multi-chain world, the chains balance traffic between one another. You have similar chains specializing for the same use case&#x2F;target audience. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;vega.xyz&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Vega&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;projectserum.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future#&#x2F;&quot;&gt;Serum&lt;&#x2F;a&gt; on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;solana.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Solana&lt;&#x2F;a&gt; both provide decentralized fast derivatives markets. If one of them reaches its maximum throughput of transactions or orderbook size the unsatisfied demand would shift to the under-utilized competitor.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resiliency&quot;&gt;Resiliency&lt;&#x2F;h2&gt;
&lt;p&gt;The whole is more resilient, because a single-chain is ironically a central point of failure which is vulnerable to e.g. hacks (flaws in the low-level runtime or consensus implementation), decreasing adoption (aging language e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Solidity?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Solidity&lt;&#x2F;a&gt;), and miner&#x2F;validator support (mining, staking becomes unprofitable). Here a competitor chain could easily step in as a fallback. Analog to having a risk-spread basket on different (e.g. collateralized, synthetic) stable coins on one chain, one could easily imagine utilizing different chains (with their own unique securities characteristics) to de-risk chain-wide failures.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;synergies&quot;&gt;Synergies&lt;&#x2F;h2&gt;
&lt;p&gt;And most importantly, synergies will emerge. Different chains, each with their unique characteristics can work together to build something that wouldn’t be possible alone. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bitcoin?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Bitcoin&lt;&#x2F;a&gt; is the reserve crypto currency. It has by far the most proof-of-work securing it as well as the longest track record of operation as a crypto currency. In it’s wrapped form it has been used on automated market makers, as collateral for stablecoins or loans. It&#x27;s even possible to take a leveraged position on bitcoin without touching a centralized exchange, have a look at &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.sovryn.app&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=multi-chain-future&quot;&gt;Sovryn&lt;&#x2F;a&gt;. This wouldn&#x27;t have been possible two years ago.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;building-bridges&quot;&gt;Building Bridges&lt;&#x2F;h2&gt;
&lt;p&gt;I hope that I could convince you with these brief examples. They are just the tip of the iceberg. With this article, I’d like to encourage a view that embraces diversity within groups and shared commonalities among groups alike. A view that helps us better understand shared values and visions and to have mutual respect and cooperate with one another.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Trust in Blockchains and Smart Contracts</title>
          <pubDate>Wed, 18 Mar 2020 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/trust-in-blockchains-and-smartcontracts/</link>
          <guid>https://www.madewithtea.com/posts/trust-in-blockchains-and-smartcontracts/</guid>
          <description xml:base="https://www.madewithtea.com/posts/trust-in-blockchains-and-smartcontracts/">&lt;p&gt;This is a piece on trust, so let’s start this with the status quo of trust in a centralized (silos) architecture of the internet. In a centralized scenario, one has to trust the centralized entity. Looking back on the last ten years of security breaches and privacy scandals, we can clearly summarize, that either people (users) don’t care enough about data privacy and security to stop trusting centralized entities or they have no viable alternative. It is this lack of clear alternatives that has allowed centralized infrastructure providers to exploit trust, the effect of which is often opaque to those exploited.&lt;&#x2F;p&gt;
&lt;p&gt;Big companies have sold hundred of millions of user data to hundreds of companies. The biggest effect of user data monetization has been to energize even more companies to bait you for your clicks, likes, poll responses, IQ tests, real-time location and much more, exploiting that data for avaricious ends. The masses happily ever after use and abuse their little pocket casino, it’s a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.theatlantic.com&#x2F;technology&#x2F;archive&#x2F;2018&#x2F;08&#x2F;the-age-of-privacy-nihilism-is-here&#x2F;568198&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;lost cause&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;So why should the masses care about decentralized contracts?&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;do-we-need-trust-less&quot;&gt;Do we need Trust-less?&lt;&#x2F;h2&gt;
&lt;p&gt;In a decentralized ecosystem, trust, or the absence of it, is central. Entities in the system don’t need to trust other entities. Statements like: “We don’t trust the government, because it is printing money out of thin air.” or “We want to cut out the middle-man and decentralize the infrastructure.”, are pointing towards lacking trust into a centralized entity. The first statement caused &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcoin.org&#x2F;en&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Bitcoin&lt;&#x2F;a&gt;. The second statement is the motivation of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;ethereum.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Ethereum&lt;&#x2F;a&gt;. Now consider the following statement: If we need to trust somebody or a company (due to the lack of transparency or literacy) to run Bitcoin (e.g. exchanges, custodians) or Ethereum (e.g. contract developers or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;infura.io&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Infura&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;metamask.io&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;MetaMask&lt;&#x2F;a&gt;), then the whole discussion about true decentralization is &lt;strong&gt;pointless&lt;&#x2F;strong&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;is-everybody-on-drugs&quot;&gt;Is Everybody On Drugs?&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_DAO_(organization?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts)&quot;&gt;DAO&lt;&#x2F;a&gt; hackers gonna hack, DAO hippies and missionaries keep on preaching of a post-privacy or privacy-conserving world in smart contracts. Don’t get me wrong, I love this &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Technological_utopianism?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;techno-utopianism&lt;&#x2F;a&gt; vibe. The religious connotation is inspiring. A clever &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Nash_equilibrium?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;nash equilibrium&lt;&#x2F;a&gt; based on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Proof-of-work_system?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;proof-of-work&lt;&#x2F;a&gt; (or other approaches) allows eliminating the trust into a central party. This works great on the consensus layer (consensus about forming blocks, the source of truth). But the need for trusting in protocols in other layers, such as contracts, wallets, and external providers still remains. The essential topic of trust, the reason this all started, has fallen short in the space.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;clients&quot;&gt;Clients&lt;&#x2F;h2&gt;
&lt;p&gt;On the foundational layer, we have node clients, the software that runs on decentralized blockchain nodes. Clients are open source, and users could potentially verify if they agree with the consensus rules. The client propagates the blockchain state and enforces these rules. The CVE-2018–17144 bug, that was unintentionally merged in 2016 into Bitcoin core, allowed miners to crash any single node that they’re connected to. But even worse, it allowed the miner to create new bitcoins at will, exceeding the 21 million hard cap limit that is currently in place, read the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcoincore.org&#x2F;en&#x2F;2018&#x2F;09&#x2F;20&#x2F;notice&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;full disclosure&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Another more recent bug was found just a couple of day before the Constantinople release of Ethereum. The smart contract auditing firm &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;chainsecurity&#x2F;constantinople-enables-new-reentrancy-attack-ace4088297d9?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;ChainSecurity&lt;&#x2F;a&gt; discovered the flaw in Ethereum Improvement (EIP) 1283 that would let attackers steal funds from users and make it “cheaper to do certain things on-chain, especially things that are currently ‘excessively’ expensive.”. Geth and Parity quickly released new versions reverting the future-fork on a particular block &amp;amp; encouraging updating to that version to prevent a chain split.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;data-providers&quot;&gt;Data Providers&lt;&#x2F;h2&gt;
&lt;p&gt;The second layer could be seen as blockchain data providers, such as node operators and APIs to blockchain data. A very central, and very trusted entity in the Ethereum space, is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;infura.io&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Infura&lt;&#x2F;a&gt;. Infura is used as a backend for any &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;metamask.io&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;MetaMask&lt;&#x2F;a&gt; wallet. It’s the single-point-of-failure. Here, it shows the power of the default. As an Infura or wallet provider, you don’t only have tremendous access to contextual data of your users, but you’re also shaping how people understand and integrate this new technology into their workflows and lives.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;smart-contracts&quot;&gt;Smart Contracts&lt;&#x2F;h2&gt;
&lt;p&gt;The third layer, smart contracts. I remember people saying contracts are immutable and unstoppable. Let me set something straight, Ethereum contracts are Turing complete, that means there will be bugs (such as the one exploited in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;The_DAO_%28organization%29?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;DAO hack&lt;&#x2F;a&gt;) and intentional backdoors. We cannot even say with certainty, who owns the contract. Who has the power to upgrade functionality, stop functionality, mint and burn tokens? To understand what are the rules defined in the contract, a computer program, one has to be able to read contract code written in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;solidity.readthedocs.io&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Solidity&lt;&#x2F;a&gt; or some other language.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;wallets-and-exchanges&quot;&gt;Wallets and Exchanges&lt;&#x2F;h2&gt;
&lt;p&gt;The fourth layer, decentralized wallets and exchanges. The assets and functionality supported by wallets determine what exists. If a wallet supports ERC20, but not ERC721, then the latter does simply not exist for the user. In the case of exchanges, they have power over what chain is behind the brand “Bitcoin” or “Ethereum”. Further, listing or de-listing of blockchains and coins corresponds to let live or die for 99% of the users.&lt;&#x2F;p&gt;
&lt;p&gt;For better user experience, users trust the service, letting exchanges hold custody of their funds. History showed that exchanges get hacked, loose liquidity and steal the user’s money. As Andreas, the Bitcoin Jesus, likes to say “Not your key? Not your Bitcoin.”. He advises people to store their cryptocurrency on their own wallets, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.forbes.com&#x2F;sites&#x2F;samantharadocchia&#x2F;2019&#x2F;01&#x2F;02&#x2F;2018-a-year-of-historic-exchange-hacks&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts#69b3b0c04a14&quot;&gt;2018, record-breaking year for exchange hacks&lt;&#x2F;a&gt;. And that’s not all, wallets and exchanges have tremendous contextual data (Know-Your-Customer) of the users and can profile user liquidity, link funds from bank wire transfer to trades to potential dark-net transactions. Selling user data has always been a profitable business it seems.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;measuring-decentralization&quot;&gt;Measuring Decentralization&lt;&#x2F;h2&gt;
&lt;p&gt;For shedding light on how decentralized the wealth of a network is, we at TokenAnalyst wrote an article, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;tokenanalyst&#x2F;who-invests-in-icos-50d9ad627506?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Who invests in ICOs?&lt;&#x2F;a&gt;, on the level of centralization inherent in holders of ICO tokens. Another related piece is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;tokenanalyst&#x2F;classifying-ethereum-users-using-blockchain-data-dd6edb867de3?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Classifying Ethereum users using blockchain data&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Balaji S. Srinivasan, CTO of Coinbase, wrote an interesting article on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;news.earn.com&#x2F;quantifying-decentralization-e39db233c28e?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=trust-in-blockchains-and-smartcontracts&quot;&gt;Quantifying Decentralization&lt;&#x2F;a&gt; and proposes the Nakamoto coefficient as a simple measure to quantify decentralization, incorporating a distribution of wealth over a population, or distribution of commits among the developers. Based on this measure, Bitcoin might be “more decentralized” than Ethereum. However, more decentralization, based on the distribution of ownership in the community, does not imply that people don’t need to trust the system, with all its sub-systems and layers above.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;trust-and-transparency&quot;&gt;Trust and Transparency&lt;&#x2F;h2&gt;
&lt;p&gt;The goal of this post is to increase awareness of the layers of trust still involved. We would like to see trust and transparency as central as decentralization in discussions and conferences to come. Further, instead of preaching tech-utopianism (true decentralization), let’s be real and educate users about what’s possible, what’s not and what information &amp;amp; power asymmetries exist, to enable them to make the right (trustworthy) choice.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Kafcache: Memcached and Kafka Streams</title>
          <pubDate>Thu, 03 Oct 2019 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/kafcache-memcached-and-kafka-streams/</link>
          <guid>https://www.madewithtea.com/posts/kafcache-memcached-and-kafka-streams/</guid>
          <description xml:base="https://www.madewithtea.com/posts/kafcache-memcached-and-kafka-streams/">&lt;p&gt;Head over to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;kafcache?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=kafcache-memcached-and-kafka-streams&quot;&gt;Kafcache&lt;&#x2F;a&gt; repository and try it out.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kafka-streams&quot;&gt;Kafka Streams&lt;&#x2F;h2&gt;
&lt;p&gt;Kafka Streams is a wonderful library for stream processing building on top of a resilient Kafka cluster. Kafka Streams applications, think of it as stream processors or microservices, consume from topics and write to Kafka topics. Either stateless or stateful. For the latter, one can persist state with an out-of-the-box RocksDB or in-memory backend. RocksDB writes state to disk which can, depending on the setup, survive a restart of the Kafka streams application or restart of the host instance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-does-it-matter&quot;&gt;Why does it matter?&lt;&#x2F;h2&gt;
&lt;p&gt;However, in certain scenarios, writing to disk is simply too slow and results in higher processing latency. At TokenAnalyst, we take low latency serious and try to minimize performance bottlenecks where possible. We&#x27;re running our processing services on memory-optimized AWS instance storing our full state in memory. Instead of using the provided in-memory implementation we&#x27;re experimenting with a epheremal memcached storage backend, I call the bridge library &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;kafcache?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=kafcache-memcached-and-kafka-streams&quot;&gt;Kafcache&lt;&#x2F;a&gt;. The provided Kafka Streams in-memory implementation is designed for small state that can easily be held in the JVM heap space. However, our state ranges easily from 100GiB to 200GiB.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kafcache&quot;&gt;Kafcache&lt;&#x2F;h2&gt;
&lt;p&gt;Kafcache is built on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;cb372&#x2F;scalacache?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=kafcache-memcached-and-kafka-streams&quot;&gt;ScalaCache&lt;&#x2F;a&gt; allowing other supported cache backends, such as Redis, as well. On the Kafka side, it&#x27;s implemented using the KeyValueStore backend serializing data with ByteArray serdes for key and values. Due to the basic nature of memcached operations, range queries e.g. for window queries are not implemented. As an effect, the memcached backend cannot be used for windowed KTables.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Reliable Fast Access to On-Chain Data</title>
          <pubDate>Tue, 18 Jun 2019 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/reliable-fast-access-to-on-chain-data/</link>
          <guid>https://www.madewithtea.com/posts/reliable-fast-access-to-on-chain-data/</guid>
          <description xml:base="https://www.madewithtea.com/posts/reliable-fast-access-to-on-chain-data/">&lt;p&gt;At &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.tokenanalyst.io&#x2F;?ref=madewithtea&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;TokenAnalyst&lt;&#x2F;a&gt;, we are building the core infrastructure to integrate, clean, and analyze blockchain data. Data on a blockchain is also known as on-chain data. We offer both historical and low-latency data streams of on-chain data across multiple blockchains.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-we-use-apache-kafka-and-the-confluent-platform&quot;&gt;How we use Apache Kafka and the Confluent Platform&lt;&#x2F;h2&gt;
&lt;p&gt;Apache Kafka® is the central data hub of our company. At TokenAnalyst, we’re using Kafka for ingestion of blockchain data—which is directly pushed from our cluster of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;bitcoin.org&#x2F;en&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Bitcoin&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;ethereum.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Ethereum&lt;&#x2F;a&gt; nodes—to different streams of transformation and loading processes.&lt;&#x2F;p&gt;
&lt;p&gt;Loading involves batching and storing data in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;avro.apache.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Avro&lt;&#x2F;a&gt; for replay and schema evolution, as well as in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;parquet.apache.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Parquet&lt;&#x2F;a&gt; for optimized batch processing in AWS Athena. A big challenge is to support and manage multiple semantically enriched data models for the same underlying data, e.g., into a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;research.tokenanalyst.io&#x2F;how-to-load-bitcoin-into-neo4j-in-one-day&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;graph data model to trace value flow&lt;&#x2F;a&gt; or into a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MapReduce?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;MapReduce-compatible&lt;&#x2F;a&gt; data model of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Unspent_transaction_output?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;UTXO-based&lt;&#x2F;a&gt; Bitcoin blockchain.&lt;&#x2F;p&gt;
&lt;p&gt;One can easily imagine that the Confluent Schema Registry is extremely helpful for typeability and systematic evolution of our models. Access to the data lake and raw data streams is self-provisioned which allows us to work in parallel, and to scale to support multiple protocols (e.g., the decentralized exchange protocol &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;0x.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;0x&lt;&#x2F;a&gt;) that are built on top of different chains.&lt;&#x2F;p&gt;
&lt;p&gt;On the event streaming side, we offer reliable low-latency data streams for financial applications based on Kafka Streams. Kafka Streams allows us to focus on our business logic leveraging its out-of-the-box high availability and fault tolerance. A very central and custom component of our data pipeline, the block confirmer, is built on top of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.confluent.io&#x2F;current&#x2F;streams&#x2F;developer-guide&#x2F;processor-api.html?_ga=2.153881147.2001080538.1562405091-2053895828.1558532168&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Processor API&lt;&#x2F;a&gt;, as we will discuss later in the Block confirmer based on Kafka Streams section.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-does-on-chain-data-matter&quot;&gt;Why does on-chain data matter?&lt;&#x2F;h2&gt;
&lt;p&gt;A public ledger could potentially serve not only as a publicly accessible ledger for money or asset transactions but also as a ledger of interactions on a shared decentralized data infrastructure. Any event, from IoT-supported delivery, trade, real estate transfer, to a bet in a prediction market is timestamped, censorship-resistant, and provable.&lt;&#x2F;p&gt;
&lt;p&gt;The blockchain as a data structure is, in essence, a giant, shared immutable log, lending itself perfectly for event sourcing and (replayed) stream processing. Interestingly, blockchain technology is reducing the need for trust, but &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;trust-in-blockchain-and-smart-contracts.html?ref=confluent&quot;&gt;doesn’t make it obsolete&lt;&#x2F;a&gt;. The required trust comes from transparency. And transparency is realized by surfacing and decoding the data that is stored on the blockchain.&lt;&#x2F;p&gt;
&lt;p&gt;Without looking too far into the future—blockchain companies, public entities, and governments rely on analytics of blockchain data for different motives, ranging from simple runtime monitoring of a smart contract to live trades made on a decentralized exchange, or revenue reports of potentially decentralized autonomous organisations or companies.&lt;&#x2F;p&gt;
&lt;p&gt;The importance of on-chain data will become ubiquitous, prompting potential on- and off-chain data joins, such as on-chain value transactions or token holdings with traditional user or customer profiles. For example, we recently examined data on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;research.tokenanalyst.io&#x2F;under-the-hood-of-the-world-computer&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Ethereum smart contract interactions&lt;&#x2F;a&gt; and clearly identified patterns of usage that could inform future development in what is essentially a machine dominated ecosystem.&lt;&#x2F;p&gt;
&lt;p&gt;Accessing on-chain data requires setting up nodes, which turns out to be not as easy as we thought, due to overcoming &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;research.tokenanalyst.io&#x2F;weird-quirks-we-found-in-ethereum-nodes&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;different quirks&lt;&#x2F;a&gt; we encountered or data discrepancies between versions. Furthermore, another challenge is keeping them in sync with the network. For zero downtime, and to ensure the highest standards in data quality and reliability, we decided to use Kafka and the Confluent Platform.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;reliable-fast-access-to-on-chain-data&#x2F;%7Bfilename%7D&#x2F;images&#x2F;confluentblogpost.jpg&quot; alt=&quot;Architecture diagram&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cluster-of-ethereum-nodes-ethereum-to-kafka-bridge&quot;&gt;Cluster of Ethereum nodes, Ethereum-to-Kafka bridge&lt;&#x2F;h2&gt;
&lt;p&gt;Right now, our focus lies on Ethereum. To interface with the peer-to-peer network, we have node templates written in Terraform, which allow us to easily deploy and bootstrap nodes across the planet in different AWS regions. We use the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;go-ethereum?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Geth&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.parity.io&#x2F;ethereum&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Parity&lt;&#x2F;a&gt;  clients. Both provide a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;JSON-RPC?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;JSON-RPC&lt;&#x2F;a&gt; interface that enables us to subscribe to recent block updates (recently mined blocks). A new block is mined on average every 15 seconds. Complementary data types such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@preethikasireddy&#x2F;how-does-ethereum-work-anyway-22d1df506369?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;transaction receipts, event logs, and state diffs&lt;&#x2F;a&gt; are also extracted.&lt;&#x2F;p&gt;
&lt;p&gt;To bridge the gap between different Ethereum clients and Kafka, we developed an in-house solution named Ethsync, written in Scala, which allows us to propagate the data in a reliable at-least-once manner. Each node plus Ethsync is pushing the data to its corresponding Kafka topic. It’s important to note that we need to run multiple nodes for redundancy because nodes can run out of sync or simply crash. The block updates pushed to the topics are the blocks that the client accepts as a new valid block. However, due to the nature of the blockchain, forks of the blockchain might happen (an alternative chain becomes longer and causes the other chain to be invalidated). Therefore, previously valid blocks can become invalid.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;block-confirmer-based-on-kafka-streams&quot;&gt;Block confirmer based on Kafka Streams&lt;&#x2F;h2&gt;
&lt;p&gt;To prevent using invalid blocks in downstream aggregate calculations, for example, we developed a block confirmer component that is based on Kafka Streams in Scala. It resolves reorganisation scenarios by temporarily keeping blocks, and only propagates them when a threshold of a number of confirmations (children to that block are mined) is reached.&lt;&#x2F;p&gt;
&lt;p&gt;For this, we keep a tree of parents and children blocks (with forks), as well as the original data, in a Kafka Streams state store as seen in Figure 1. We’re storing the state as updates to the same key. In production, each new block produces a state record update of 150 KB on average. When forks happen, we usually see two forks, but sometimes up to four forks in a six-confirmation time window.&lt;&#x2F;p&gt;
&lt;p&gt;The confirmer not only solves the challenge of verifying the canonical chain but also outputs every confirmed block with effectively once semantics by discarding already registered and already confirmed blocks. Building that component on Kafka Streams allowed us to leverage on fault tolerance recovery mechanisms, such as failover instances and state recovery. This is great for rolling deploys for zero-downtime environments.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;our-api-and-software-development-kit-sdk&quot;&gt;Our API and software development kit (SDK)&lt;&#x2F;h2&gt;
&lt;p&gt;In the big picture, our &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;docs.tokenanalyst.io&#x2F;?ref=madewithtea&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;API and SDK&lt;&#x2F;a&gt; allow customers to retrieve both historical data and reports, and to subscribe to low-latency data streams of raw and contextualized on-chain data. The API backend and SDK are both written in TypeScript. To access the result records of Kafka Streams processors and KSQL processing queries like filtering, aggregates, and anomaly detection, we use the kafka-node and avro-schema-registry JavaScript libraries. The latter enables us to verify the correct output types to prevent schema inconsistencies, inconsistencies with the SDK, and implicitly with external customer infrastructure.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;The hype is currently omnipresent, and it’s not going away soon. We foresee a demand for on-chain data, or trusted data, going forward. It doesn’t just come from the perspective of financial transactions and regulations but, more importantly, from the use cases that smart contracts will enable in the near future. As a startup, we try to maximize the impact of our work effort in the right direction under very limited resources. The latter requires leveraging proven components such as the Confluent Platform to build resilient data pipelines.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;remark&quot;&gt;Remark&lt;&#x2F;h2&gt;
&lt;p&gt;This article was published first on the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.confluent.io&#x2F;blog&#x2F;reliable-fast-access-to-on-chain-data-insights?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=reliable-fast-access-to-on-chain-data&quot;&gt;Confluent blog&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Weird Quirks we found in Ethereum Nodes</title>
          <pubDate>Tue, 18 Dec 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/weird-quirks-we-found-in-ethereum-nodes/</link>
          <guid>https://www.madewithtea.com/posts/weird-quirks-we-found-in-ethereum-nodes/</guid>
          <description xml:base="https://www.madewithtea.com/posts/weird-quirks-we-found-in-ethereum-nodes/">&lt;p&gt;At TokenAnalyst we are experts at hosting, running, and extracting valuable information from blockchain nodes. Through our time working with Ethereum, we encountered some interesting quirks that we&#x27;d love to share with the broader community. We work with the two top most-used Ethereum clients, namely Geth (go-ethereum), built mainly by the Ethereum Foundation, and Parity, built by Parity Technologies.&lt;&#x2F;p&gt;
&lt;p&gt;The following quirks have been found by my coworkers &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;ankitchiplunkar?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;Ankit&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sidshekhar24?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;Sid&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;madewithtea?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;myself&lt;&#x2F;a&gt;. If you have any questions regarding the following findings, we would be happy to help. There are not too many people trying to get data from nodes, but if they do, they&#x27;ll inevitably encounter these quirks at some point. The following list is anecdotal, for further references links are supplied. The first two points are particularly important to know when you set up your own node.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;1-run-ssd&quot;&gt;1. Run SSD&lt;&#x2F;h2&gt;
&lt;p&gt;Magnetic hard-drives are not optimal for running nodes; they are just too slow. SSD is a much better option. We started our full nodes on AWS t3.xlarge instances, having EBS storage attached. However, it turned out, that &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;NVM_Express?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;NVMe&lt;&#x2F;a&gt; instance storage in RAID-0 is much more cost-effective, with a 30x improvement on I&#x2F;O throughput when writing files.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;2-responsiveness&quot;&gt;2. Responsiveness&lt;&#x2F;h2&gt;
&lt;p&gt;When Geth is not in sync with the latest block, the RPC interface is unresponsive, meaning you cannot query for e.g. blocks, transactions, receipts etc. This works in Parity.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-no-error-response-standards&quot;&gt;3. No Error Response Standards&lt;&#x2F;h2&gt;
&lt;p&gt;Even though there is a standard what kind of RPC methods and parameters exist. There are no standard error responses across nodes. Hence, if you want to write software that integrates with different clients you have to parse responses dependent on the client.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;4-response-fields-not-consistent&quot;&gt;4. Response Fields not Consistent&lt;&#x2F;h2&gt;
&lt;p&gt;The fields, r, s, v of a transaction are not consistent on different clients. They&#x27;re different on Geth, Parity and Infura, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;sidshekhar24&#x2F;status&#x2F;1052896205724893184?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;reference&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;5-parity-vs-geth&quot;&gt;5. Parity vs. Geth&lt;&#x2F;h2&gt;
&lt;p&gt;Running the latest versions of Geth and Parity on the same AWS t3.xlarge instance types with EBS storage, in the same regions, Geth is more out-of-sync than Parity. This is particularly unfortunate since Geth is unresponsive while syncing. The comparison was pre-1.8.19. After we updated to 1.8.19 we experienced better performance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;6-typesafe&quot;&gt;6. Typesafe&lt;&#x2F;h2&gt;
&lt;p&gt;The JSON-RPC interface is not type-safe. That means, for data pipelines building on top of this data source, post-processing e.g. validation and typecasting is required. The &quot;standard&quot; on the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ethereum&#x2F;wiki&#x2F;wiki&#x2F;JSON-RPC?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;wiki&lt;&#x2F;a&gt; is not very enforcing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;7-traces-and-statediffs&quot;&gt;7. Traces and Statediffs&lt;&#x2F;h2&gt;
&lt;p&gt;For data, like internal transactions, state diffs, there is not an RPC standard yet. Geth is not supporting them yet, Parity has implemented them: https:&#x2F;&#x2F;wiki.parity.io&#x2F;JSONRPC-trace-module.html. The state diff result format is a bit weird, and it&#x27;s not fully consistent: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;parity-ethereum&#x2F;issues&#x2F;8937?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;see&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;8-data-bugs&quot;&gt;8. Data Bugs&lt;&#x2F;h2&gt;
&lt;p&gt;There are two ways of retrieving the latest blocks. Through HTTP polling or a kept alive web socket connection. For both ways block re-organization (a wrong block is forwarded and later discarded) is not correctly implemented on Geth and Parity, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;paritytech&#x2F;parity-ethereum&#x2F;issues&#x2F;9865?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=weird-quirks-we-found-in-ethereum-nodes&quot;&gt;see&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;9-smaller-differences&quot;&gt;9. Smaller Differences&lt;&#x2F;h2&gt;
&lt;p&gt;Multiple smaller differences between the interfaces of Geth and Parity: Uncle size is null in Parity, but does exist in Geth. Filter IDs on Geth and Parity are different. Geth assigns random IDs, and Parity uses an incremental counter.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;10-in-general&quot;&gt;10. In General&lt;&#x2F;h2&gt;
&lt;p&gt;The consensus rules among clients have to match in order to make Ethereum work, but everything else, e.g. the exposed API, or RPC interface can be totally different. Take each client with a grain of salt.&lt;&#x2F;p&gt;
&lt;p&gt;To sum it up.&lt;&#x2F;p&gt;
&lt;p&gt;Through the process of setting up our infrastructure. We learned that when building fault-tolerant, highly reliable, and mission-critical application on top of Ethereum, it is not enough to rely on the functionality of specific Ethereum clients. An extremely deep understanding of how nodes work, what they need, and how to orchestrate them is required to ensure effectively zero downtime along the whole data pipeline.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Using Monix with Kafka, Avro and Schema Registry</title>
          <pubDate>Sun, 30 Sep 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/using-monix-with-kafka-schemas/</link>
          <guid>https://www.madewithtea.com/posts/using-monix-with-kafka-schemas/</guid>
          <description xml:base="https://www.madewithtea.com/posts/using-monix-with-kafka-schemas/">&lt;p&gt;Working with Confluent&#x27;s schema registry solves problems like where to store schemas in a polyglot environment, how to keep track of versions and how to evolve schemas over time. It&#x27;s also required to have implicit schemas for your Kafka topics when using &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.confluent.io&#x2F;hub&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;Kafka connectors&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.confluent.io&#x2F;product&#x2F;ksql&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;KSQL&lt;&#x2F;a&gt;. If you don&#x27;t need the former, you might as well just use a type of &lt;em&gt;Array[Byte]&lt;&#x2F;em&gt; and serialize with &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;sksamuel&#x2F;avro4s?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;Avro4s&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;julianpeeters&#x2F;avrohugger?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;avrohugger&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;So what&#x27;s Monix? &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;monix.io&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;Monix&lt;&#x2F;a&gt; is a high-performance Scala &#x2F; Scala.js library for composing asynchronous, event-based programs. It&#x27;s leveraging concepts of Scalaz&#x27; task and provides further out-of-the-box compatibility with the Reactive Streams protocol. The developers behind Monix also created &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;monix&#x2F;monix-kafka?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;monix-kafka&lt;&#x2F;a&gt;, which is a wrapper for Kafka to easily integrate with Monix-based services. In addition, a consumer can also be turned into an &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;monix.io&#x2F;docs&#x2F;3x&#x2F;reactive&#x2F;observable.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;Observable&lt;&#x2F;a&gt;, see also this &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;monix.io&#x2F;docs&#x2F;3x&#x2F;reactive&#x2F;observable-comparisons.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=using-monix-with-kafka-schemas&quot;&gt;comparison&lt;&#x2F;a&gt; to Akka Actors, Akka Streams and FS2.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;add-dependencies&quot;&gt;Add Dependencies&lt;&#x2F;h2&gt;
&lt;p&gt;When using monix-kafka, you instantiate your Kafka producer by passing a configuration and type parameters of how your records look like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;val producerCfg = KafkaProducerConfig.default.copy(bootstrapServers = brokers.toList)
private val producer = KafkaProducer[Array[Byte], Array[Byte]](producerCfg, scheduler)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The type for both key and value is the supported &lt;em&gt;Array[Byte]&lt;&#x2F;em&gt; type. However, let&#x27;s serialize with Confluent&#x27;s Avro serializer. For this, first, we need to add the missing link, a new resolver URL and the serializer dependency. Be sure you add the right version depending the schema registry you&#x27;re running.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scala&quot; class=&quot;language-scala &quot;&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;    resolvers += &amp;quot;confluent.io&amp;quot; at &amp;quot;http:&amp;#x2F;&amp;#x2F;packages.confluent.io&amp;#x2F;maven&amp;#x2F;&amp;quot;
    libraryDependencies ++= &amp;quot;io.confluent&amp;quot; % &amp;quot;kafka-avro-serializer&amp;quot; % &amp;quot;5.0.0&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;extend-monix-kafka&quot;&gt;Extend Monix Kafka&lt;&#x2F;h2&gt;
&lt;p&gt;Thanks to implicits we can easily add it to extend the capabilities of Monix&#x27; Kafka producer and consumer. Let&#x27;s create an Object that contains functions to create implicit &lt;em&gt;MonixSerializer&lt;&#x2F;em&gt; and &lt;em&gt;MonixDeserializer&lt;&#x2F;em&gt; values given a serializer, deserializer configuration and a boolean parameter to indicate whether it is the record key (needed by Confluent&#x27;s Kafka Avro Serializer). In the configuration we can now pass the schema registry URL.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scala&quot; class=&quot;language-scala &quot;&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;    import io.confluent.kafka.serializers.{KafkaAvroDeserializer, KafkaAvroSerializer}
    import monix.kafka.{Serializer =&amp;gt; MonixSerializer}
    import monix.kafka.{Deserializer =&amp;gt; MonixDeserializer}
    import collection.JavaConverters._
    
    object AvroSerializer {
      def serializer(cfg: Map[String, String], isKey: Boolean): MonixSerializer[Object] =
        MonixSerializer[Object](
          className = &amp;quot;io.confluent.kafka.serializers.KafkaAvroSerializer&amp;quot;,
          classType = classOf[KafkaAvroSerializer],
          constructor = _ =&amp;gt; {
            val serializer = new KafkaAvroSerializer()
            serializer.configure(cfg.asJava, isKey)
            serializer
          }
        )
    
       def deserializer(cfg: Map[String, String], isKey: Boolean): MonixDeserializer[Object] =
        MonixDeserializer[Object](
          className = &amp;quot;io.confluent.kafka.serializers.KafkaAvroDeserializer&amp;quot;,
          classType = classOf[KafkaAvroDeserializer],
          constructor = _ =&amp;gt; {
            val deserializer = new KafkaAvroDeserializer()
            deserializer.configure(cfg.asJava, isKey)
            deserializer
          }
        )
    }
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;monix-kafka-producer&quot;&gt;Monix Kafka Producer&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s use these implicits now to instantiate a Kafka producer which serializes to Confluent&#x27;s Avro format and uses the schema registry to lookup the schema for a specific topic, great for typesafetyness in Kafka topics. Here&#x27;s how the rest of the code looks like. It&#x27;s analogous to use Avro in the key field or instantiating a Kafka consumer.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scala&quot; class=&quot;language-scala &quot;&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;    case class RecordValue(someInt: Int)

    val serCfg = Map(&amp;quot;schema.registry.url&amp;quot; -&amp;gt; &amp;quot;http:&amp;#x2F;&amp;#x2F;schemaregistry:8081&amp;quot;)
    implicit val serializer: Serializer[Object] = AvroSerializer.serializer(serCfg, false)
    implicit val format = RecordValue[ValueFormat]

    val producerCfg = KafkaProducerConfig.default.copy(bootstrapServers = brokers.toList)
    val producer = KafkaProducer[String, Object](producerCfg, scheduler)
    
    val recordVal = format.to(RecordValue(1))
    val record = new ProducerRecord[String, Object](topic, 0, &amp;quot;key&amp;quot;, recordVal)

    val task = producer.send(record)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</description>
      </item>
      <item>
          <title>Via Negativa Minimalism</title>
          <pubDate>Sat, 25 Aug 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/via-negativa-minimalism/</link>
          <guid>https://www.madewithtea.com/posts/via-negativa-minimalism/</guid>
          <description xml:base="https://www.madewithtea.com/posts/via-negativa-minimalism/">&lt;p&gt;Readers of Antifragile by Nassim Nicholas Taleb should be familiar with the concept of ‘via negativa’ (literally &#x27;negative path&#x27;). ‘Non-doing’ is an active action and has side effects like doing. ‘Non-doing’ is generally unnoticed and undervalued. However, not doing something negative, has a neutral or even positive outcome.&lt;&#x2F;p&gt;
&lt;p&gt;Smart avoidance can therefore improve a situation. The requirement, however, is understanding or imagining how the inverse action would effect the situation. A concrete example certainly everybody would agree with, is not-smoking.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hoarding-principles&quot;&gt;Hoarding Principles&lt;&#x2F;h2&gt;
&lt;p&gt;Two other concepts, cognitive biases, I would like to introduce before connecting them with minimalism are loss aversion and the endowment effect. Both were introduced in Daniel Kahneman’s bestseller Thinking, Fast and Slow.&lt;&#x2F;p&gt;
&lt;p&gt;Loss aversion in a nutshell: It refers to peoples tendency to strongly prefer avoiding losses to acquiring gains. I would call it the first Hoarding-principle. The endowment effect is a hypothesis that people ascribe more value to things when people own them. That’s the second hoarding principle. The experiments underpinning the concepts are very interesting reads.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;choices&quot;&gt;Choices&lt;&#x2F;h2&gt;
&lt;p&gt;From a functional perspective, objects are utility. The decision of buying or owning something relies on the a-priori estimation whether the object would provide utility. We don’t know, and usually we are not taking other people as reference (except for signalling purposes) since we believe we’re so special, read Daniel Gilbert’s Stumbling on Happiness.&lt;&#x2F;p&gt;
&lt;p&gt;So, choices are not-buying or buying (let’s simplify rent to buy). Given a finite amount of money and time, we need to select objects that have a good utility prospect. We are exploring the space of goods. We are window shopping. Endless possibilities, choices, nudged by ads, friends, idols and so on. Got something? Good. Let’s integrate it into your life.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;integration&quot;&gt;Integration&lt;&#x2F;h2&gt;
&lt;p&gt;Depending on how accurate you were estimating the long-term utility value of your acquired object, it paid off, or it was throwing money out of the window. The spectrum ranges from introspective consumers to buyers on a FOMO basis. Sure, personal traits and influences play a big role here, but exploration is required. How else can we determine if it provides utility?&lt;&#x2F;p&gt;
&lt;p&gt;But here we should remind ourselves to the first concept: Via Negativa. What if we would not buy into the desire. Would it have a positive effect on our life? Clearly, it would go unnoticed, even if it was an active decision of not-buying. Can you imagine your life without the object, but something else taking its place with more utility value? What would this other object be?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;exploration-and-exploitation&quot;&gt;Exploration and Exploitation&lt;&#x2F;h2&gt;
&lt;p&gt;It’s tough, and trying it out is the only choice. Otherwise we would be stuck not-buying anything new, because of fear of being disappointed. In other words, we’d be stuck in a local optima. It’s the balance between exploration and exploitation. Exploration refers to buying new things, without a-priori knowledge whether it provides the desired utility value (taking risk), and exploitation refers to the long-term benefit of utility value provided by the object (not-taking risk, but might be stuck in a local optima).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;hoarding-bias&quot;&gt;Hoarding Bias&lt;&#x2F;h2&gt;
&lt;p&gt;In Minimalism, we ask ourselves the question, do I need this, does it make me happy, do I really want to focus on this, do I want to maintain it? In the rational case after an evaluation period, we decide to keep or sell it. This happened to me recently with a fitness tracker which I decided to sell (it didn’t make me happy, and I didn’t like to wear it all-the-time).&lt;&#x2F;p&gt;
&lt;p&gt;However, as I referenced earlier, the hoarding principles are deeply integrated in us humans. The cognitive biases of loss aversion and endowment effect bias us to simply keep our stuff. With both, a just-in-case (loss aversion) and a ‘it’s more worth than it’s actually worth’ mindset (endowment effect). Overcoming this, is the path towards minimalism. Put the objects in doubt into a box, and put it in the attic or basement. If you don’t miss it, get rid of it. Even throw it away (it’s worth less then you actually think).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;references&quot;&gt;References&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote an article about minimalism, which offers questions you can ask yourself when you consider buying new things. I hope both articles inspire you to become a more conscious consumer and owner. And please share the article if you enjoyed it.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Countermeasures Against Phone Addiction</title>
          <pubDate>Mon, 02 Apr 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/countermeasures-against-phone-addiction/</link>
          <guid>https://www.madewithtea.com/posts/countermeasures-against-phone-addiction/</guid>
          <description xml:base="https://www.madewithtea.com/posts/countermeasures-against-phone-addiction/">&lt;p&gt;In my previous article, I wrote about the pleasures of using your smartphone, specifically using addictive apps, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;pleasure-happiness-and-feedback-loops.html&quot;&gt;Pleasure, Happiness and Feedback-Loops&lt;&#x2F;a&gt;. Addictive apps use dopamine-driven feedback loops. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Dopamine?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;Dopamine&lt;&#x2F;a&gt; corresponds to short-term pleasure, and to much of it &lt;strong&gt;leads to addiction&lt;&#x2F;strong&gt;. It is typically experienced alone, and makes the brain say “This feels good, I want more”. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Serotonin?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;Serotonin&lt;&#x2F;a&gt; on the other hand is closely related to long-term happiness, like contentment. It’s generally shared, like spending time with friends, family, colleagues etc. and it makes the brain say: “This feels good, and it’s enough”. Too little of it leads to depression, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.amazon.com&#x2F;Hacking-American-Mind-Corporate-Takeover&#x2F;dp&#x2F;1101982586?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;The Hacking of the American Mind&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.businessinsider.com&#x2F;why-our-phones-are-making-us-miserable-pleasure-isnt-happiness-2018-3&#x2F;?r=US&amp;amp;IR=T&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;This Is Why our Phones are Making Us Miserable&lt;&#x2F;a&gt;. Fundamentally, seeking for pleasure doesn’t make us happy, it addicts us, going down a spiral of long-term dissatisfaction.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;form-a-habit-every-single-day&quot;&gt;Form a Habit Every Single Day&lt;&#x2F;h2&gt;
&lt;p&gt;And when I write &lt;em&gt;addictive apps&lt;&#x2F;em&gt;, I mean even Reddit, Mail, WhatsApp, Telegram, Signal, Snapshot and what not. I like to outline five essential principles that are based on my experience and which everybody can potentially integrate in their lives. After that list, I’ll describe my ideal day routine. I’m by no means close to forming a habit - there are exceptions, I just try to avoid those as hard as I can. Let&#x27;s start the list with a bold clever quote.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;cite&gt;&quot;You will never change your life until you change something you do daily. The secret of success is found in your daily routine.&quot;&lt;&#x2F;cite&gt;
— John C. Maxwell&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;h2 id=&quot;principles&quot;&gt;Principles&lt;&#x2F;h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Don’t take your phone into your sleeping room or bath room.&lt;&#x2F;strong&gt; There is no excuse. If you’re using it as an alarm, buy a radio alarm clock (just buy a used one, if money is your excuse). I know a lot people take showers while listening to Spotify or Apple Music. Just buy a shower radio. It’s simple, always works and sometimes water-proof. Don’t use your phone on the toilet, that’s just the worst. Yep, guess we all do or did it.  Take a magazine, news paper whatever, or just enjoy the quiet time.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;When going to bed, put your phone on airplane mode.&lt;&#x2F;strong&gt; (when you’re not expecting a super important call) put it in a drawer (outside sleeping room and bath room). I’m putting mine in a draw right under my desk. Out of sight, out of mind.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Disable all notifications&lt;&#x2F;strong&gt; for messages apps etc. disable also notification badges and push notifications. I believe it&#x27;s a much healthier approach to encourage people to call you for the important parts in life.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;When you meet somebody e.g. in a cafe&lt;&#x2F;strong&gt;, don’t put your phone on the table. No matter if you put it upside down or not. Putting your phone on the table makes the opposite person feel less important to spend attention to.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Put your phone on grayscale mode.&lt;&#x2F;strong&gt; It really makes a difference, just try it out, you’ll feel that you’re less attracted to the phone. iOS devices can be put on a grayscale mode easily &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.iphonelife.com&#x2F;blog&#x2F;5&#x2F;tip-day-how-turn-grayscale-mode-ios-8?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;without any additional app&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;day-routine&quot;&gt;Day Routine&lt;&#x2F;h2&gt;
&lt;p&gt;My ideal routine is the following: Waking up by a radio alarm clock. Getting a shower. Afterwards, I&#x27;m having breakfast. After breakfast, I actively decide if I want to check my phone for messages. I disable airplane mode and get the latest updates. Hopefully I don’t have to write back to someone, in urgent cases I plan to call people to give a response. Putting it back into the drawer or taking it with me. At work, don’t put it on desk, keep it in your pocket or bag. After work, put it in the drawer. Before sleep set it to airplane mode.&lt;&#x2F;p&gt;
&lt;p&gt;I hope that article inspired you to rework your phone habits. Let’s enjoy life more by watching our phones less.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;reading-list&quot;&gt;Reading List&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;medium.com&#x2F;@quanders&#x2F;the-only-human-tech-reading-list-ever-9ccb6298890d?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;Humane Technology Reading List&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.theatlantic.com&#x2F;magazine&#x2F;archive&#x2F;2017&#x2F;09&#x2F;has-the-smartphone-destroyed-a-generation&#x2F;534198&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;Have Smartphones Destroyed a Generation?&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ted.com&#x2F;talks&#x2F;tristan_harris_the_manipulative_tricks_tech_companies_use_to_capture_your_attention?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;How a Handful of Tech Companies Control Billions of Minds Everyday&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ted.com&#x2F;talks&#x2F;tristan_harris_how_better_tech_could_protect_us_from_distraction?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;How Better Tech Could Protect Us From Distraction&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.theodysseyonline.com&#x2F;24-hours-without-my-phone?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;What I Learned in 24 Hours Without My Phone&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;embed&#x2F;tf9ZhU7zF8s?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;This Panda is Dancing - Time Well Spent Video&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=GufhzLSmqMs&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;Your Brain Is Getting Hacked Video&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=As8XkJNaHbs&amp;amp;feature=youtu.be&amp;amp;t=5m20s&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=countermeasures-against-phone-addiction&quot;&gt;Simon Sinek on Millennials in the Workplace&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Monitoring Kafka Streams Metrics via JMX</title>
          <pubDate>Thu, 09 Feb 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/monitoring-metrics-kafka-streams/</link>
          <guid>https://www.madewithtea.com/posts/monitoring-metrics-kafka-streams/</guid>
          <description xml:base="https://www.madewithtea.com/posts/monitoring-metrics-kafka-streams/">&lt;p&gt;The documentation on monitoring of &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;documentation&#x2F;streams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Kafka Streams&lt;&#x2F;a&gt; is a bit sparse, so I will shed some light on interesting metrics to monitor when running Kafka Streams applications. In addition to Kafka producer, consumer metrics, each Kafka Streams application has &lt;em&gt;stream-metrics&lt;&#x2F;em&gt;, &lt;em&gt;stream-rocksdb-state-metrics&lt;&#x2F;em&gt;, and &lt;em&gt;stream-rocksdb-window-metrics&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In this article, let&#x27;s focus on the stream processing metrics only. I&#x27;ll present a way to access the metrics using the command-line application &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;wiki.cyclopsgroup.org&#x2F;jmxterm&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;jmxterm&lt;&#x2F;a&gt;, and I&#x27;ll give some insights about the semantics of these metrics, so you can use them for monitoring and alerting. For an introduction into monitoring, I highly recommend the &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;monitoring-metrics-kafka-streams&#x2F;#resources&quot;&gt;Monitoring 101&lt;&#x2F;a&gt; in the resources section at the end. Among other &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;monitoring-metrics-kafka-streams&#x2F;#resources&quot;&gt;valueable resources&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;jmx-exposed-stream-metrics&quot;&gt;JMX-exposed Stream Metrics&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s dive into the metrics. Start jmxterm and open a connection to the local JVM with the Kafka Streams application running. For connecting you can use the &lt;em&gt;open&lt;&#x2F;em&gt; command. The command &lt;em&gt;beans&lt;&#x2F;em&gt; will show you all exposed beans. In this article I will only cover the global stream metrics. The same metrics are defined for each processor. When using jmxterm, it is important to switch &lt;em&gt;client-id&lt;&#x2F;em&gt; and &lt;em&gt;type&lt;&#x2F;em&gt; in the bean name when querying, otherwise, jmxterm responds with bean name invalid, see my &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;search-hadoop.com&#x2F;m&#x2F;Kafka&#x2F;uyzND1HWVV61uorew1?subj=Cannot+access+Kafka+Streams+JMX+metrics+using+jmxterm&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;problem description&lt;&#x2F;a&gt; and Sachin Mittal&#x27;s workaround on the helpful Kafka &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;contact.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;users mailing list&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;$&amp;gt;info -d kafka.streams -b kafka.streams:type=stream-metrics,
client-id=app-fdddffde-5b10-44c8-82dc-3e343cdab829-StreamThread-1

#mbean = kafka.streams:type=stream-metrics,
client-id=app-fdddffde-5b10-44c8-82dc-3e343cdab829-StreamThread-1
#class name = org.apache.kafka.common.metrics.JmxReporter$KafkaMbean
# attributes
  %0   - commit-latency-avg (double, r)
  %1   - commit-latency-max (double, r)
  %2   - commit-rate (double, r)
  %3   - poll-latency-avg (double, r)
  %4   - poll-latency-max (double, r)
  %5   - poll-rate (double, r)
  %6   - process-latency-avg (double, r)
  %7   - process-latency-max (double, r)
  %8   - process-rate (double, r)
  %9   - punctuate-latency-avg (double, r)
  %10  - punctuate-latency-max (double, r)
  %11  - punctuate-rate (double, r)
  %12  - skipped-records-rate (double, r)
  %13  - task-closed-rate (double, r)
  %14  - task-created-rate (double, r)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The latencies are in milliseconds, the rates are per-second. To get the values of an attribute use the &lt;em&gt;get&lt;&#x2F;em&gt; command. For the original descriptions of these metrics, have a look at this
&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;kafka&#x2F;blob&#x2F;7de22453bbd05a7ac629543e09626ac6987ce306&#x2F;streams&#x2F;src&#x2F;main&#x2F;java&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;streams&#x2F;processor&#x2F;internals&#x2F;StreamThread.java?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#L1118&quot;&gt;code&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;semantics&quot;&gt;Semantics&lt;&#x2F;h2&gt;
&lt;p&gt;To understand what these metrics are measuring, we need to know the answers to the following questions in Kafka jargon: What is a commit request? What is a poll? What is a process? What is a task? What is puncate? And finally: What are skipped records?&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;A commit or &lt;em&gt;commit request&lt;&#x2F;em&gt; is a request from a Kafka consumer to the broker to commit a certain processed offset to mark the latest offset it read from.&lt;&#x2F;li&gt;
&lt;li&gt;A poll or &lt;em&gt;long poll&lt;&#x2F;em&gt; is the process of fetching records from the broker to the consumer. If there are no new records available it will block (busy-wait). Metrics for polling are only updated if long polling is used in the consumer. However, it will be initialized with zero.&lt;&#x2F;li&gt;
&lt;li&gt;A process is a function evaluation of a StreamTask in a StreamThread associated with a PartitionGroup, compare with documentation on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#stream-partitions-and-tasks&quot;&gt;stream partition&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#threading-model&quot;&gt;thread model&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;kafka&#x2F;blob&#x2F;trunk&#x2F;streams&#x2F;src&#x2F;main&#x2F;java&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;streams&#x2F;processor&#x2F;internals&#x2F;StreamTask.java?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#L177&quot;&gt;code&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;The &lt;em&gt;punctuate&lt;&#x2F;em&gt; method is part of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;documentation&#x2F;streams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#streams_processor&quot;&gt;Low-Level Processer API&lt;&#x2F;a&gt;. The punctuate method is executed periodically based on elapsed time. When you use the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;documentation&#x2F;streams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#streams_dsl&quot;&gt;High-Level Streams DSL&lt;&#x2F;a&gt; you don&#x27;t have to bother with this metric, since it is not used. However, it will be initialized with zero.&lt;&#x2F;li&gt;
&lt;li&gt;The record is skipped when it is added to the StreamTask record queue. In the code documentation it says, a record is skipped when it has an invalid timestamp, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;kafka&#x2F;blob&#x2F;7de22453bbd05a7ac629543e09626ac6987ce306&#x2F;streams&#x2F;src&#x2F;main&#x2F;java&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;streams&#x2F;processor&#x2F;internals&#x2F;StreamTask.java#L148&quot;&gt;StreamTask code&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;kafka&#x2F;blob&#x2F;7de22453bbd05a7ac629543e09626ac6987ce306&#x2F;streams&#x2F;src&#x2F;main&#x2F;java&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;streams&#x2F;processor&#x2F;internals&#x2F;StreamThread.java#L621&quot;&gt;StreamThread code&lt;&#x2F;a&gt;. So this should be zero, otherwise, you might want to check your timestamps.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;custom-metrics-reporter&quot;&gt;Custom Metrics Reporter&lt;&#x2F;h2&gt;
&lt;p&gt;You might want to push your metrics to e.g. statsd or some SaaS to monitor and alert on anomalies or thresholds. There are some libraries available for Kafka, which might work for Kafka Streams metrics as well. Otherwise, you can fairly simple add your own custom metrics reporter by creating a class which implements the MetricsReporter interface and passing the class name to the &lt;em&gt;metric.reporters&lt;&#x2F;em&gt; parameter in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;documentation&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#streamsconfigs&quot;&gt;StreamsConfig&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you found a mistake, or like to add something, please feel free to send me a mail under &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;pages&#x2F;contact.html&quot;&gt;contact&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kafka-related-resources&quot;&gt;Kafka-related Resources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.confluent.io&#x2F;blog&#x2F;introducing-kafka-streams-stream-processing-made-simple?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Introducing Kafka Streams: Stream Processing Made Simple&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DataDog&#x2F;the-monitor&#x2F;blob&#x2F;master&#x2F;kafka&#x2F;collecting-kafka-performance-metrics.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Collecting Kafka Performance Metrics&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DataDog&#x2F;the-monitor&#x2F;blob&#x2F;master&#x2F;kafka&#x2F;monitoring-kafka-performance-metrics.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Monitoring Kafka Performance Metrics&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;documentation&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx#kafka_streams_monitoring&quot;&gt;Official Kafka Streams Documentation Monitoring&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.hugopicado.com&#x2F;2016&#x2F;10&#x2F;05&#x2F;stream-processing-with-kafka-streams.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Stream Processing with Kafka Streams by Hugo Picado&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cwiki.apache.org&#x2F;confluence&#x2F;display&#x2F;KAFKA&#x2F;Kafka+papers+and+presentations?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Kafka Papers and Presentations Wiki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DataDog&#x2F;the-monitor&#x2F;blob&#x2F;master&#x2F;monitoring-101&#x2F;monitoring_101_alerting_on_what_matters.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Monitoring 101: Alerting on What Matters&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DataDog&#x2F;the-monitor&#x2F;blob&#x2F;master&#x2F;monitoring-101&#x2F;monitoring_101_collecting_the_right_data.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Monitoring 101: Collecting the Right Data&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;DataDog&#x2F;the-monitor&#x2F;blob&#x2F;master&#x2F;monitoring-101&#x2F;monitoring_101_investigating_performance_issues.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Monitoring 101: Investigating Performance Issues&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.ctheu.com&#x2F;2017&#x2F;02&#x2F;14&#x2F;all-the-things-we-can-do-with-jmx&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;All the things we can do with JMX&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;255kb&#x2F;stack-on-a-budget&#x2F;blob&#x2F;master&#x2F;pages&#x2F;error-reporting.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Free Tier: Error Reporting&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;255kb&#x2F;stack-on-a-budget&#x2F;blob&#x2F;master&#x2F;pages&#x2F;monitoring.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;Free Tier: Monitoring&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;onurakpolat&#x2F;awesome-analytics?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=monitoring-kafka-metrics-using-jmx&quot;&gt;List of Analytics Tools&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Released Mocked Streams for Apache Kafka</title>
          <pubDate>Mon, 24 Oct 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/releasing-mocked-streams/</link>
          <guid>https://www.madewithtea.com/posts/releasing-mocked-streams/</guid>
          <description xml:base="https://www.madewithtea.com/posts/releasing-mocked-streams/">&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;Kafka Streams&lt;&#x2F;a&gt; is a deployment-agnostic stream processing library written in Java. Even though Kafka has a great test coverage, there is no easy way to write unit-tests for processing topologies, until now. I released &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;Mocked Streams&lt;&#x2F;a&gt; for Scala, which simply allows you to unit-test multi-input and output stateful stream topologies (since Apache Kafka &amp;gt;= 0.10.1) without Zookeeper and Kafka Brokers in your favorite Scala testing framework e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.scalatest.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;ScalaTest&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;etorreborre.github.io&#x2F;specs2&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;Specs2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;import com.madewithtea.mockedstreams.MockedStreams

val input = Seq((&amp;quot;x&amp;quot;, &amp;quot;v1&amp;quot;), (&amp;quot;y&amp;quot;, &amp;quot;v2&amp;quot;))
val expe = Seq((&amp;quot;x&amp;quot;, &amp;quot;V1&amp;quot;), (&amp;quot;y&amp;quot;, &amp;quot;V2&amp;quot;))
val strings = Serdes.String()

MockedStreams()
  .topology { builder =&amp;gt; builder.stream(...) [...] }
  .input(&amp;quot;topic-in&amp;quot;, strings, strings, input)
  .output(&amp;quot;topic-out&amp;quot;, strings, strings, expe.size) shouldEqual expe
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;mocked-streams&quot;&gt;Mocked Streams&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;Mocked Streams 1.0&lt;&#x2F;a&gt; is a library which allows you to do the latter without much boilerplate code and in your favourite Scala testing framework. It wraps the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;kafka&#x2F;blob&#x2F;trunk&#x2F;streams&#x2F;src&#x2F;test&#x2F;java&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;test&#x2F;ProcessorTopologyTestDriver.java?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;org.apache.kafka.test.ProcessorTopologyTestDriver&lt;&#x2F;a&gt; class, but adds more syntactic sugar to keep your test code simple. The features of the 1.0 release include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Multiple input and output streams&lt;&#x2F;li&gt;
&lt;li&gt;Specify your topologies as a function: (KStreamBuilder =&amp;gt; Unit)&lt;&#x2F;li&gt;
&lt;li&gt;Use .config to pass your Kafka Streams configuration (e.g. Timestamp extractor)&lt;&#x2F;li&gt;
&lt;li&gt;Use .outputTable to match against the compacted table output as Map[K,V]&lt;&#x2F;li&gt;
&lt;li&gt;Support for Scala 2.11.8&lt;&#x2F;li&gt;
&lt;li&gt;Support for Apache Kafka 0.10.1.0&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;multiple-inputs-and-outputs&quot;&gt;Multiple Inputs and Outputs&lt;&#x2F;h2&gt;
&lt;pre&gt;&lt;code&gt;val ms = MockedStreams()
  .topology { builder =&amp;gt; builder.stream(...) [...] }
  .input(&amp;quot;in-a&amp;quot;, strings, ints, inputA)
  .input(&amp;quot;in-b&amp;quot;, strings, ints, inputB)
  .stores(Seq(&amp;quot;store-name&amp;quot;))

ms.output(&amp;quot;out-a&amp;quot;, strings, ints, expA.size) shouldEqual(expectedA)
ms.output(&amp;quot;out-b&amp;quot;, strings, ints, expB.size) shouldEqual(expectedB)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;&#x2F;h2&gt;
&lt;p&gt;See the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams&#x2F;blob&#x2F;master&#x2F;README.md?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;README&lt;&#x2F;a&gt; for using Mocked Streams. For examples check out the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams&#x2F;blob&#x2F;master&#x2F;src&#x2F;test&#x2F;scala&#x2F;MockedStreamsSpec.scala?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;test code of Mocked Streams&lt;&#x2F;a&gt; itself. Mocked Streams is also located in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;search.maven.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams#artifactdetails%7Ccom.madewithtea%7Cmockedstreams_2.11%7C1.0.0%7Cjar&quot;&gt;Maven Central Repository&lt;&#x2F;a&gt;, hence you just need to add:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;libraryDependencies += &amp;quot;com.madewithtea&amp;quot; %% &amp;quot;mockedstreams&amp;quot; % &amp;quot;1.0.0&amp;quot; % &amp;quot;test&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you have any questions or issues regarding Mocked Streams, get in touch via &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=releasing-mocked-streams&quot;&gt;Github&lt;&#x2F;a&gt;. Alternatively, you can get in &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;pages&#x2F;contact.html&quot;&gt;contact via mail&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Stateful Streaming in Spark and Kafka Streams</title>
          <pubDate>Sat, 15 Oct 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/stateful-streaming-in-kafka-streams-and-spark/</link>
          <guid>https://www.madewithtea.com/posts/stateful-streaming-in-kafka-streams-and-spark/</guid>
          <description xml:base="https://www.madewithtea.com/posts/stateful-streaming-in-kafka-streams-and-spark/">&lt;p&gt;TLDR: This article is about aggregates in stateful stream processing. It covers two &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#aggregates-in-spark-streaming&quot;&gt;concrete examples&lt;&#x2F;a&gt; in Apache Spark (using the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;2.0.0-preview&#x2F;streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Streaming API&lt;&#x2F;a&gt; with &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#mapwithstate&quot;&gt;mapWithState&lt;&#x2F;a&gt;) and Apache Kafka (using the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;developer-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#kafka-streams-dsl&quot;&gt;high-level DSL&lt;&#x2F;a&gt; in Streams). Spark Streaming and Kafka Streams differ much. Therefore the reader can get to know both approaches and can decide which fits best. I discuss what &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#aggregates&quot;&gt;features for real-time aggregates&lt;&#x2F;a&gt; besides reliability and scaling requirements we would like to see covered (e.g. to be queryable, re-processable, versionable, composable, unlimited updates, providing retention times, downsampling and having end-to-end guarantees). In the end, I will discuss the example code, also along those requirements.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;&#x2F;h2&gt;
&lt;p&gt;I will start this article by giving an &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#streaming-frameworks&quot;&gt;overview of streaming frameworks&lt;&#x2F;a&gt;. After, I will discuss &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#aggregates&quot;&gt;requirements on aggregates&lt;&#x2F;a&gt;. I would like to present an &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#aggregates-in-spark-streaming&quot;&gt;example in Spark&lt;&#x2F;a&gt; using Spark Streaming&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#mapwithstate&quot;&gt;mapWithState&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;#aggregates-in-kafka-streams&quot;&gt;one example in Kafka Streams&lt;&#x2F;a&gt; using the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.1&#x2F;streams&#x2F;developer-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#kafka-streams-dsl&quot;&gt;high-level DSL&lt;&#x2F;a&gt;. Spark as a cluster computation framework relying on &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hadoop.apache.org&#x2F;docs&#x2F;r1.2.1&#x2F;hdfs_design.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;HDFS&lt;&#x2F;a&gt; and external databases such as &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cassandra.apache.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Cassandra&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;hbase.apache.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;HBase&lt;&#x2F;a&gt; is very different from Kafka Streams, a topology-based deployment-agnostic processing library, which heavily relies on the distributed log system &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Kafka&lt;&#x2F;a&gt; and a key-value store (e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;rocksdb.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;RocksDB&lt;&#x2F;a&gt;). Spark Streaming and Kafka Streams differ much. Therefore the reader can get to know both approaches and can decide which fits best.&lt;&#x2F;p&gt;
&lt;p&gt;For a complete example application in Kafka Streams, check out my previous article &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;processing-tweets-with-kafka-streams.html&quot;&gt;Processing Tweets with Kafka Streams&lt;&#x2F;a&gt;. For the examples some experience with Spark and Kafka is needed, I will refer to introduction articles.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;streaming-analytics&quot;&gt;Streaming Analytics&lt;&#x2F;h2&gt;
&lt;p&gt;Data-driven decision making in companies is becoming essential to stay competitive (adoption rates nearly tripled from 11 - 30% between 2005 and 2010, see this &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.aeaweb.org&#x2F;articles?id=10.1257%2Faer.p20161016&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;article&lt;&#x2F;a&gt;). Analytics are valuable for both business, business partners or customers.  Data warehousing, data mining and learning from archived data is essential to measure KPIs, gain insights and to plan a strategy to reach the companies goal. With a market size of $5.1 billion in 2015, it is forecasted to $53.7 billion by 2017, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.vldb.org&#x2F;pvldb&#x2F;vol8&#x2F;p2040-Kejariwal.pdf?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;here&lt;&#x2F;a&gt;. However, in recent years, analytics have been transitioning from offline (batch) to online (streaming) approaches.&lt;&#x2F;p&gt;
&lt;p&gt;Streaming analytics is extensively used in a wide variety of domains such as healthcare, e-commerce, financial services, telecommunications, energy and utilities, manufacturing, government, and transportation. This &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.vldb.org&#x2F;pvldb&#x2F;vol8&#x2F;p2040-Kejariwal.pdf?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;paper&lt;&#x2F;a&gt; summarizes growth forecasts in the listed fields.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;streaming-frameworks&quot;&gt;Streaming Frameworks&lt;&#x2F;h2&gt;
&lt;p&gt;For a conceptual introduction into stream processing, I like to refer to the introduction articles &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.oreilly.com&#x2F;ideas&#x2F;the-world-beyond-batch-streaming-101?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Streaming 101&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.oreilly.com&#x2F;ideas&#x2F;the-world-beyond-batch-streaming-102?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Streaming 102&lt;&#x2F;a&gt;. A list of vast streaming framework can be found &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;manuzhang&#x2F;awesome-streaming?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;here&lt;&#x2F;a&gt;. The following table shows Apache streaming frameworks. The original article where I got this useful comparison from is: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;databaseline.wordpress.com&#x2F;2016&#x2F;03&#x2F;12&#x2F;an-overview-of-apache-streaming-technologies&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;An Overview of Apache Streaming Technologies&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;%7Bfilename%7D&#x2F;images&#x2F;streaming.png&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;stateful-streaming-in-kafka-streams-and-spark&#x2F;%7Bfilename%7D&#x2F;images&#x2F;streaming.png&quot; alt=&quot;Streaming Frameworks&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The key differences of streaming frameworks are, when they process events (event-at-a-time or (micro-)batches, how the architecture looks like (cluster framework, library or distributed workers), what processing guarantees they have, e.g. at-least-once (duplicates possible), exactly-once processing and small latency or near-zero latency. When it comes to stateful streaming, it is also important how and where the state is stored and for how long. General problems like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Scalability?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;scalability&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Elasticity_(cloud_computing?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;elasticity&lt;&#x2F;a&gt;), &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fault_tolerance?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;fault tolerancy&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;High_availability?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;high-availability&lt;&#x2F;a&gt; and sub-problems like state migration, versioning of data &#x2F; computation and reprocessing are also important to compare. All in all, as usual it highly depends on the requirements. As I wrote in the beginning, I would like to focus on aggregates with Apache Spark Streaming and Kafka Streams. But first, let&#x27;s define what an aggregate is and what features we would like to have on aggregates.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;aggregates&quot;&gt;Aggregates&lt;&#x2F;h2&gt;
&lt;p&gt;A streaming computation could be simple as a shell command, a web request, a database insert, any arbitrary execution, or output data in form of an updated aggregate, a stream of transformed events, new data triggered by input events, new data dependent on external lookups in other tables (e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Machine_learning?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#Theory&quot;&gt;machine learning models&lt;&#x2F;a&gt;) and so forth. The use case of maintaining a realtime aggregate is however the most interesting one since it needs to store a state somehow, somewhere.&lt;&#x2F;p&gt;
&lt;p&gt;For example, an aggregate could be the total amount of viewers of a page in a certain time window. This aggregate depends on events fired in this event time window. Desired features of such an aggregate, besides reliability, scalability and fault tolerancy, would be: to be queryable (like a database, give me the current state of the aggregate), reprocessable (if the aggregated was computed in the wrong way), versionable (we have multiple versions of the aggregate since the computation changed), composable (one aggregate depends on another aggregate), unlimited updates (no watermarking needed, you should be able to always update an aggregate, some use case exceptions later on), sending updates (changes) of aggregates downstream (for consumers, e.g. analytics UI), providing retention times (when is this aggregate obsolete or not useful anymore), downsampling (different resolutions of an aggregate value) and having end-to-end guarantees (is this event used for the current aggregate?).&lt;&#x2F;p&gt;
&lt;!-- Incorperate this here
Queryable: in batch, single rows, polling the latest data before switching to realtime updates?
Reprocesable: if the aggregates was computed in the wrong way, major outtage, data losses, Sourcing raw events
Versionable: Sooner or later there will be new topologies, and you might want to do versioning, to be backward compatible on the consumer side.
Composable: An aggregate might depend on other aggregates. You want aggregates to be composable, because then you can save computation
Unlimited updates: In the ideal world the aggregate would be a table entry which can get changed often. Table dualism. Late arrivals
Sending Changes: You want only to have the updates to an aggregate, so downstream you for instance have a realtime view.
Retention Times &#x2F; downsampling: Maybe you want to have your aggregates in different resolutions, different sample sizes or time frequencies. Or your aggregate will not be needed at all after a certain time.
End-to-End: Having the guarantee that all the events will be processed, and that they get processed from ingesting the raw events to storing the resulting aggregates or their changes.
--&gt;
&lt;p&gt;In the next sections I will give the two concrete examples and will then refer to those features some of them rely on design decisions of the overall architecture and some directly depend on the streaming framework.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;aggregates-in-spark-streaming&quot;&gt;Aggregates in Spark Streaming&lt;&#x2F;h2&gt;
&lt;p&gt;Even though Spark 2.0.0 introduced &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;databricks.com&#x2F;blog&#x2F;2016&#x2F;07&#x2F;28&#x2F;structured-streaming-in-apache-spark.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Structured Streaming&lt;&#x2F;a&gt;, in which you should be able to perform SQL queries on infinite data frames representing streams, Structured Streaming is an ALPHA RELEASE, and the APIs are still experimental. Many important features are not available yet, e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;latest&#x2F;structured-streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#unsupported-operations&quot;&gt;joins between streams&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;latest&#x2F;structured-streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#unsupported-operations&quot;&gt;the distinct operation&lt;&#x2F;a&gt; and the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;latest&#x2F;structured-streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#basic-concepts&quot;&gt;update output mode&lt;&#x2F;a&gt; for aggregate changes. Therefore, for general purpose stream processing, I highly recommend to stick to the Spark Streaming API, which before 1.6 supplied the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jaceklaskowski.gitbooks.io&#x2F;mastering-apache-spark&#x2F;content&#x2F;spark-streaming&#x2F;spark-streaming-operators-stateful.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#updateStateByKey&quot;&gt;updateStateByKey&lt;&#x2F;a&gt; DStream function, and since 1.6 the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;latest&#x2F;structured-streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#basic-concepts&quot;&gt;mapWithState&lt;&#x2F;a&gt; DStream function. See &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;databricks.com&#x2F;blog&#x2F;2016&#x2F;02&#x2F;01&#x2F;faster-stateful-stream-processing-in-apache-spark-streaming.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Faster Stateful Stream Processing in Apache Spark&#x27;s Streaming&lt;&#x2F;a&gt; for an official comparison. As another reference, I also like to refer to the online book Mastering Apache Spark, chapter &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jaceklaskowski.gitbooks.io&#x2F;mastering-apache-spark&#x2F;content&#x2F;spark-streaming-operators-stateful.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Working with State using Stateful Operations&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;don-t-use-updatestatebykey&quot;&gt;Don&#x27;t Use UpdateStateByKey&lt;&#x2F;h2&gt;
&lt;p&gt;The big caveat of using updateStateByKey is, that on each new value the transformation iterates over the entire state store, regardless whether a new value for each key has been consumed or not, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;databricks.com&#x2F;blog&#x2F;2016&#x2F;02&#x2F;01&#x2F;faster-stateful-stream-processing-in-apache-spark-streaming.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;here&lt;&#x2F;a&gt;. Smaller caveats are: no timeout mechanism (if you need it) and it will only return what is stored. In Spark 1.6, mapWithState was introduced, which has a built-in timeout mechanism, partial updates, arbitrary return types and an initial state. A well-written comparison can be found here: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;asyncified.io&#x2F;2016&#x2F;07&#x2F;31&#x2F;exploring-stateful-streaming-with-apache-spark&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Exploring Stateful Streaming with Apache Spark&lt;&#x2F;a&gt;. Okay, let me show a simple example employing mapWithState: Maintaining a distinct set of strings per key.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;mapwithstate&quot;&gt;mapWithState&lt;&#x2F;h2&gt;
&lt;p&gt;mapWithState has the following function signature: mapWithState[StateType, MappedType](spec: StateSpec[K, V, StateType, MappedType]). K, V are the types of the input stream, the StateType the type of the state stored and MappedType the returning stream type. The StateSpec can be defined by a function. In the following example, let us assume an input stream of type DStream[(SiteId, String)] representing page view events partitioned by SiteId. The string can represent a user id.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scala&quot; class=&quot;language-scala &quot;&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;def stateSpecFunc(batchTime: Time, key: SiteId, value: Option[String],
                   state: State[List[String]]): Option[(SiteId, Int)] = {
  val v = value.get
  if (state.exists()) {
    val currentSet = state.get()
    if (currentSet.contains(v)) {
      None
    } else {
      state.update(currentSet.++(List(v)))
      Some(key, state.get.size)
    }
  } else {
    state.update(List(v))
    Some(key, state.get.size)
  }
}
val spec = StateSpec.function(stateSpecFunc)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;As you can see, we have to do the state initialization and retrieval manually. As discussed, we can return an arbitrary DStream with mapWithState. We now use this trackStateFunc in our processing graph.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scala&quot; class=&quot;language-scala &quot;&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;val stateSpec = StateSpec.function(trackStateFunc _).numPartitions(2)
val stateStream = input.mapWithState(stateSpec)
val stateSnapshotStream = stateStream.stateSnapshots().map {
  state =&amp;gt; (state._1, state._2.size)
}
stateSnapshotStream.print()

ssc.checkpoint(&amp;quot;file:&amp;#x2F;tmp&amp;#x2F;&amp;quot;)
ssc.start() &amp;#x2F;&amp;#x2F; Start the computation
ssc.awaitTermination() &amp;#x2F;&amp;#x2F; Wait for the computation to terminate
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s re-visit the desired features of aggregates which we would like to have. First, the aggregate should be queryable. The state is stored virtually in an RDD and physically spread over the cluster worker nodes. Besides there is no official API to query the state. Therefore we need to store the aggregates somewhere downstream e.g. database. We can reprocess the data if we stored the original events (for instance in a Kafka log) and reprocess by event time. For event time processing we need to time-bucket events manually by a groupByKey operation. If reprocessing is a common use case, the iteration is an important variable when it comes to storing and querying. Versioning in the database and in the query API needs to manually implemented. Since we can return whatever data type in the state function, we can compose aggregates.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s discuss unlimited updates to an aggregate. So, if you deal with aggregates which are temporary and will be closed (e.g. an event window, any events after a certain &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.oreilly.com&#x2F;ideas&#x2F;the-world-beyond-batch-streaming-102?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;watermark&lt;&#x2F;a&gt; will be discarded for that window, even if the events lies in that window), you can push the final aggregate downstream and save into e.g. a database. In the case when the aggregate is not temporary, the RDD will grow, and gets eventually spilled onto disk. Retention times and downsampling needs to be done manually. Exactly-once processing guarantees can be achieved with extra effort, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;latest&#x2F;streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#with-kafka-direct-api&quot;&gt;here&lt;&#x2F;a&gt;. As already discussed, both functions mapWithState and updateByStateKey the state is implemented using the RDD concept, therefore &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;2.0.0&#x2F;streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#checkpointing&quot;&gt;checkpointing&lt;&#x2F;a&gt; for recovery in case of failure is also supported by the state (in the file system as well as HDFS).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;towards-structured-streaming&quot;&gt;Towards Structured Streaming&lt;&#x2F;h2&gt;
&lt;p&gt;Tathagata Das mentions in his talk &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=rl8dIzTpxrI&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Apache Spark 2.0: A Deep Dive Into Structured Streaming&lt;&#x2F;a&gt; some pain points which led to the development of structured streaming, including not having the concept of event-time processing, using the same engine for batch and streaming, and the difficulty of reasoning about end-to-end guarantees. Interestingly, he also mentions the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;rl8dIzTpxrI?t=506&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;table stream duality&lt;&#x2F;a&gt;, originally described &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.confluent.io&#x2F;blog&#x2F;introducing-kafka-streams-stream-processing-made-simple?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;here&lt;&#x2F;a&gt; by Jay Kreps. This concept inspired the Kafka people to fundamentally rethink stream processing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;aggregates-in-kafka-streams&quot;&gt;Aggregates in Kafka Streams&lt;&#x2F;h2&gt;
&lt;p&gt;The latest version 0.10 of Kafka introduces Kafka Streams. It is a deployment-agnostic stream processing library with &lt;em&gt;event-at-a-time&lt;&#x2F;em&gt; (not micro-batch) semantics written in Java. It scales via &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#parallelism-model&quot;&gt;partitioning and tasks&lt;&#x2F;a&gt;, is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#fault-tolerance&quot;&gt;fault-tolerant&lt;&#x2F;a&gt; and has an &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#processing-guarantees&quot;&gt;at-least-once&lt;&#x2F;a&gt; guarantee when it comes to processing records. The framework tries to focus on simplicity in the semantics. Especially the &#x27;Tables and Streams are Dual&#x27; concept is very interesting, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=zVK12q9PpQg&amp;amp;feature=youtu.be&amp;amp;t=166&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Jay Kreps&lt;&#x2F;a&gt; or &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=QkDYkB6Q16Q&amp;amp;feature=youtu.be&amp;amp;t=1469&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Guozhang Wang&lt;&#x2F;a&gt; explaining it. To give you a short example:&lt;&#x2F;p&gt;
&lt;p&gt;A stream can be aggregated into a table, e.g. an aggregation of a stream in a time window can be seen as a table for a time span in a local state. The change log contains every update to that table. So you can transform the windowed aggregate to a stream of changes, which in term can be used in other aggregates or even joins. If you have not already read it, I highly recommend reading the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.confluent.io&#x2F;blog&#x2F;introducing-kafka-streams-stream-processing-made-simple?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;introduction article&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Without further introduction let us examine the example. In this example, we do same processing: Maintaining a set of strings by key. The processing is defined in the high-level DSL in the latest Kafka 0.10.1, see the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;developer-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#kafka-streams-dsl&quot;&gt;documentation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;scala&quot; class=&quot;language-scala &quot;&gt;&lt;code class=&quot;language-scala&quot; data-lang=&quot;scala&quot;&gt;class SetInitializer[V] extends Initializer[Set[V]] {
  override def apply() = Set[V]()
}

class DistinctAggregator[K, V] extends Aggregator[K, V, Set[V]] {
  override def apply(k: K, v: V, t: Set[V]) = t + v
}

builder
  .stream(Serde[String], Serde[String], topic)
  .groupByKey(Serdes.String(), Serdes.String())
  .aggregate(
    new SetInitializer[String],
    new DistinctAggregator[String, String],
    Serde[List[String]],
    &amp;quot;store-name&amp;quot;)
  .toStream
  .to(Serde[String], Serde[Set[String], output-topic)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The return type of the aggregation is a &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;0100&#x2F;javadoc&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;streams&#x2F;kstream&#x2F;KTable.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;KTable&lt;&#x2F;a&gt; reference. Since we are interested in the change stream, we transform the KTable back to a change stream. The operation after is the most interesting part, also check &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=QkDYkB6Q16Q&amp;amp;feature=youtu.be&amp;amp;t=1642&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;this example&lt;&#x2F;a&gt; of Guozhang Wang. Aggregate() on a KStream can be used to store an aggregate state. One aggregate per key is maintained. The aggregate itself must be defined by the user with a custom &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;0100&#x2F;javadoc&#x2F;index.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Initializer&lt;&#x2F;a&gt; and an &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;0100&#x2F;javadoc&#x2F;index.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Aggregator&lt;&#x2F;a&gt;. You might also want to check out other articles. Here are the official Confluent &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;confluentinc&#x2F;examples&#x2F;tree&#x2F;kafka-0.10.0.1-cp-3.0.1&#x2F;kafka-streams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#examples-scala&quot;&gt;Scala&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;confluentinc&#x2F;examples&#x2F;tree&#x2F;kafka-0.10.0.1-cp-3.0.1&#x2F;kafka-streams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#examples-java&quot;&gt;Java examples&lt;&#x2F;a&gt;. The documentation for these examples can be found &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.1&#x2F;streams&#x2F;developer-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#code-examples&quot;&gt;here&lt;&#x2F;a&gt;. Another good resource is the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cwiki.apache.org&#x2F;confluence&#x2F;display&#x2F;KAFKA&#x2F;Kafka+papers+and+presentations?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Kafka papers and presentations&lt;&#x2F;a&gt; wiki page.&lt;&#x2F;p&gt;
&lt;!--
## Features

* State migration, when migrating the state cannot be retrieved
* Fault tolerancy
* Reliability
* Reprocessing from the Kafka log
* Open issue of versioning
* State can be retrieved easily querable
* No overhead cluster
* No big ecosystem like Spark
--&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;If you want to start using it seriously, I recommend you to read the referenced articles. If you have any questions or suggestions on my article, feel free to send me an email. See the &lt;a href=&quot;&#x2F;pages&#x2F;contact.html&quot;&gt;contact page&lt;&#x2F;a&gt; for contact information.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;resources&quot;&gt;Resources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.oreilly.com&#x2F;ideas&#x2F;the-world-beyond-batch-streaming-101?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Streaming 101&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.oreilly.com&#x2F;ideas&#x2F;the-world-beyond-batch-streaming-102?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Streaming 102&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;manuzhang&#x2F;awesome-streaming?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Awesome Streaming List&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;spark-related-resources&quot;&gt;Spark-related Resources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;databaseline.wordpress.com&#x2F;2016&#x2F;03&#x2F;12&#x2F;an-overview-of-apache-streaming-technologies&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;An Overview of Apache Streaming Technologies&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;databricks.com&#x2F;blog&#x2F;2016&#x2F;07&#x2F;28&#x2F;structured-streaming-in-apache-spark.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Structured Streaming in Spark&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;spark.apache.org&#x2F;docs&#x2F;2.0.0-preview&#x2F;streaming-programming-guide.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Spark Streaming Programming Guide&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;databricks.com&#x2F;blog&#x2F;2016&#x2F;02&#x2F;01&#x2F;faster-stateful-stream-processing-in-apache-spark-streaming.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Faster Stateful Stream Processing in Apache Spark&#x27;s Streaming&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;jaceklaskowski.gitbooks.io&#x2F;mastering-apache-spark&#x2F;content&#x2F;spark-streaming-operators-stateful.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Working with State Stateful Operations in Mastering Spark&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;asyncified.io&#x2F;2016&#x2F;07&#x2F;31&#x2F;exploring-stateful-streaming-with-apache-spark&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Exploring Stateful Streaming with Spark&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;kafka-related-resources&quot;&gt;Kafka-related Resources&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.confluent.io&#x2F;blog&#x2F;introducing-kafka-streams-stream-processing-made-simple?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Introducing Kafka Streams: Stream Processing Made Simple&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;kafka.apache.org&#x2F;documentation.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark#streams&quot;&gt;Official Kafka Streams Documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;processing-tweets-with-kafka-streams.html&quot;&gt;Processing Tweets with Kafka Streams&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;cwiki.apache.org&#x2F;confluence&#x2F;display&#x2F;KAFKA&#x2F;Kafka+papers+and+presentations?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Kafka Papers and Presentations Wiki&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;developers.linecorp.com&#x2F;blog&#x2F;?p=3960&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Applying Kafka Streams for internal message delivery pipeline&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;youtu.be&#x2F;zVK12q9PpQg?t=166&amp;amp;utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=stateful-streaming-in-kafka-streams-and-spark&quot;&gt;Table-Stream Dualism Video&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Testing Topologies with Kafka Streams</title>
          <pubDate>Fri, 30 Sep 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/testing-topologies-with-kafka-streams/</link>
          <guid>https://www.madewithtea.com/posts/testing-topologies-with-kafka-streams/</guid>
          <description xml:base="https://www.madewithtea.com/posts/testing-topologies-with-kafka-streams/">&lt;p&gt;UPDATE: I released the first version of Mocked Streams. See &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;released-mocked-streams-for-apache-kafka.html&quot;&gt;Released Mocked Streams for Apache Kafka&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;TLDR: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;Kafka Streams&lt;&#x2F;a&gt; is a deployment-agnostic stream processing library written in Java. Even though Kafka has a great test coverage, there is no helper code for writing unit-tests for your own Kafka Streams topologies. I wrote a little helper library &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;Mocked Streams&lt;&#x2F;a&gt; in Scala, which allows you to create lightweight parallelizable unit-tests for your topologies without running a full Kafka cluster neither an embedded one. See this &lt;a href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;testing-topologies-with-kafka-streams&#x2F;#unit-testing-topologies&quot;&gt;code example&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;kafka-streams&quot;&gt;Kafka Streams&lt;&#x2F;h2&gt;
&lt;p&gt;The latest version 0.10 of Kafka introduces Kafka Streams. It is a deployment-agnostic stream processing library with &lt;em&gt;event-at-a-time&lt;&#x2F;em&gt; (not micro-batch) semantics written in Java. It scales via &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams#parallelism-model&quot;&gt;partitioning and tasks&lt;&#x2F;a&gt;, is &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams#fault-tolerance&quot;&gt;fault-tolerant&lt;&#x2F;a&gt; and has an &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;docs.confluent.io&#x2F;3.0.0&#x2F;streams&#x2F;architecture.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams#processing-guarantees&quot;&gt;at-least-once&lt;&#x2F;a&gt; guarantee when it comes to processing records. If you have not already read it, I highly recommend reading the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.confluent.io&#x2F;blog&#x2F;introducing-kafka-streams-stream-processing-made-simple&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;introduction article&lt;&#x2F;a&gt; to Kafka Streams.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;unit-testing-topologies&quot;&gt;Unit-Testing Topologies&lt;&#x2F;h2&gt;
&lt;p&gt;If you had your first hands-on Kafka Streams already, you might have noticed that there is no easy way to unit-test your topologies. Even though Kafka is documented quite well, it lacks, for now, of good documentation of how to test. In general, you can choose between running a full Kafka cluster including Zookeeper in your environment, running an embedded Kafka broker and Zookeeper, like in this Kafka Streams &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;kafka&#x2F;blob&#x2F;trunk&#x2F;streams&#x2F;src&#x2F;test&#x2F;java&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;streams&#x2F;integration&#x2F;KStreamAggregationIntegrationTest.java?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;integration test&lt;&#x2F;a&gt;, or you use mock producers and consumers for lightweight unit-tests of your topologies. While the first two approaches are the way to go for integration tests, we should also be able to unit-test our topologies in a simple way:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;val input = Seq((&amp;quot;x&amp;quot;, &amp;quot;v1&amp;quot;), (&amp;quot;y&amp;quot;, &amp;quot;v2&amp;quot;))
val exp = Seq((&amp;quot;x&amp;quot;, &amp;quot;V1&amp;quot;), (&amp;quot;y&amp;quot;, &amp;quot;V2&amp;quot;))
val strings = Serdes.String()

MockedStreams()
  .topology { builder =&amp;gt; builder.stream(...) [...] }
  .input(&amp;quot;topic-in&amp;quot;, strings, strings, input)
  .output(&amp;quot;topic-out&amp;quot;, strings, strings, exp.size) shouldEqual exp
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;mocked-streams&quot;&gt;Mocked Streams&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;Mocked Streams&lt;&#x2F;a&gt; is a library which allows you to do the latter without much boilerplate code and in your favourite Scala testing framework e.g. &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.scalatest.org&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;ScalaTest&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;etorreborre.github.io&#x2F;specs2&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;Specs2&lt;&#x2F;a&gt;. It wraps the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;apache&#x2F;kafka&#x2F;blob&#x2F;trunk&#x2F;streams&#x2F;src&#x2F;test&#x2F;java&#x2F;org&#x2F;apache&#x2F;kafka&#x2F;test&#x2F;ProcessorTopologyTestDriver.java?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;org.apache.kafka.test.ProcessorTopologyTestDriver&lt;&#x2F;a&gt; class, but adds more syntactic sugar to keep your test code simple. The example above is testing the following topology:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;builder.stream(strings, strings, &amp;quot;topic-in&amp;quot;)
  .map((k, v) =&amp;gt; new KeyValue(k, v.toUpperCase))
  .to(strings, strings, &amp;quot;topic-out&amp;quot;)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the example, we have only one input and one output topic. However, we are able to define multiple inputs and multiple outputs. Assuming we have a topology &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams&#x2F;blob&#x2F;master&#x2F;src&#x2F;test&#x2F;scala&#x2F;MockedStreamsSpec.scala?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;MultiInputOutputTopology&lt;&#x2F;a&gt; which consumes two input streams, does an aggregation with a local state, and sends records to two output topics, we can test it like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;val mstreams = MockedStreams()
  .topology { builder =&amp;gt; builder.stream(...) [...] }
  .input(&amp;quot;in-a&amp;quot;, strings, ints, inputA)
  .input(&amp;quot;in-b&amp;quot;, strings, ints, inputB)
  .stores(Seq(&amp;quot;store-name&amp;quot;))

mstreams.output(&amp;quot;out-a&amp;quot;, strings, ints, expA.size) shouldEqual(expectedA)
mstreams.output(&amp;quot;out-b&amp;quot;, strings, ints, expB.size) shouldEqual(expectedB)
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Note, that the order .input(...) calls is very important: When calling .output(...) Mocked Streams produces to the Kafka input topics in the same order as specified. In the example, it would produce all messages to topic &quot;out-a&quot; first, then to &quot;out-b&quot;. Each output call will start an isolated run, fetching from the specified output topic. For a better understanding I like to refer to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jpzk&#x2F;mockedstreams&#x2F;blob&#x2F;master&#x2F;src&#x2F;test&#x2F;scala&#x2F;MockedStreamsSpec.scala?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;tests&lt;&#x2F;a&gt; of Mocked Streams itself.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usage-in-the-next-release-of-kafka&quot;&gt;Usage in the Next Release of Kafka&lt;&#x2F;h2&gt;
&lt;p&gt;Personally, I work on next still unstable version 0.10.1 of Kafka. I was experiencing some issues back-porting Mocked Streams to the stable 0.10.0.1 release. Therefore, I decided to only support and distribute JARs for the next stable release. However, if you are interested in scratching your own itch, contribution &amp;amp; collaboration would be great! Unfortunately, for now, if you want to use it, you need to add Mocked Streams manually. But I will add it to the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;mvnrepository.com&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=testing-topologies-with-kafka-streams&quot;&gt;Maven Repositories&lt;&#x2F;a&gt; when the next Kafka version is released!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Minimalism and Elegant Code</title>
          <pubDate>Sun, 22 May 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://www.madewithtea.com/posts/minimalism-and-elegant-code/</link>
          <guid>https://www.madewithtea.com/posts/minimalism-and-elegant-code/</guid>
          <description xml:base="https://www.madewithtea.com/posts/minimalism-and-elegant-code/">&lt;p&gt;TLDR; The minimalism lifestyle is a mindset in which you let go of unused belongings and unimportant attachments. But how is elegant code defined? I would define it similiar to Antoine de Saint-Exupéry&#x27;s infamous definition of &lt;em&gt;elegant design&lt;&#x2F;em&gt;: Elegant design is achieved not when there is nothing left to add, but when there is nothing left to take away – In this sense, the best code is the one never written, but it does fulfill the job.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;minimalism&quot;&gt;Minimalism&lt;&#x2F;h2&gt;
&lt;p&gt;The minimalism lifestyle focuses on the true important needs, and letting go of unused belongings or unimportant attachments. It can have a huge impact in your life and I recommend to anyone who has a different relationship with old stuff, a toxic attitude of buying too much new stuff, to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;mnmlist.com&#x2F;minimalist-faqs&#x2F;?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;learn more about  minimalism&lt;&#x2F;a&gt;. I am a minimalist, and for me it became a very important mindset which counterbalances the status quo, the world of more. I wrote two other articles about that topic: &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;minimalism-the-art-of-living-with-less.html&quot;&gt;Minimalism: The Art of Living with Less&lt;&#x2F;a&gt; and &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;mindfulness-in-the-culture-of-distraction.html&quot;&gt;Mindfulness in the Culture of Distraction&lt;&#x2F;a&gt;. Even though, it became quite popular in terms of a way of living, it is also applied to a lot of other domains like &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minimal_music?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;music&lt;&#x2F;a&gt;, &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minimalism?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code#Minimalist_design_and_architecture&quot;&gt;architecture&lt;&#x2F;a&gt; and the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Minimalism_%28visual_arts%29?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;visual arts&lt;&#x2F;a&gt;, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;www.artsy.net&#x2F;gene&#x2F;minimalism?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;Artsy Minimalism&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;minimalism-and-elegant-code&#x2F;%7Bfilename%7D&#x2F;images&#x2F;minimalismcode2.jpg&quot; alt=&quot;Typewriter&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elegance&quot;&gt;Elegance&lt;&#x2F;h2&gt;
&lt;p&gt;Before we dive into minimalism and code, I want to start with an infamous definition of &lt;em&gt;elegance&lt;&#x2F;em&gt; also referenced in the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;www.catb.org&#x2F;jargon&#x2F;html&#x2F;E&#x2F;elegant.html?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;hacker jargon file&lt;&#x2F;a&gt;, also see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;english.stackexchange.com&#x2F;questions&#x2F;38837&#x2F;where-does-this-translation-of-saint-exuperys-quote-on-design-come-from?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;where it comes from&lt;&#x2F;a&gt;. In my opinion it connects elegant  engineering and minimalism very well:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The French aviator, adventurer, and author &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Antoine_de_Saint-Exup%C3%A9ry?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;Antoine de Saint-Exupéry&lt;&#x2F;a&gt;, probably best known for his classic children&#x27;s book The Little Prince, was also an aircraft designer. He gave us perhaps the best definition of engineering elegance when he said “A designer knows he has achieved perfection not when there is nothing left to add, but when there is nothing left to take away.”
&lt;cite&gt;– Jargon File&lt;&#x2F;cite&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Elegant code is what &lt;em&gt;remains&lt;&#x2F;em&gt;. Without decoration, without bloat. The pure functionality to fit the requirements – and the requirements &lt;em&gt;only&lt;&#x2F;em&gt;. On &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;http:&#x2F;&#x2F;programmers.stackexchange.com&#x2F;questions&#x2F;97912&#x2F;how-do-you-define-elegant-code?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;StackExchange&lt;&#x2F;a&gt;, there are other possible definitions of elegant code, which I like to reference to give a broader perspective. But for the next sections, let me explain why minimalism is central to elegant code. Hence, let us start with avoiding code in the first place.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;avoid-code&quot;&gt;Avoid Code&lt;&#x2F;h2&gt;
&lt;p&gt;You start something &lt;em&gt;new&lt;&#x2F;em&gt;. You get the requirements right and begin outlining the infrastructure, components and the protocol which might be needed to get the job done. This is design work, and it should be &lt;em&gt;effective&lt;&#x2F;em&gt; and &lt;em&gt;efficient&lt;&#x2F;em&gt;, but also I think, as &lt;em&gt;simple as possible&lt;&#x2F;em&gt;. Lean. The same applies on a code level. Every statement you write, could be another &lt;em&gt;bug&lt;&#x2F;em&gt;, could &lt;em&gt;distract&lt;&#x2F;em&gt; you from the core of the logic, or could even be &lt;em&gt;redundant or useless&lt;&#x2F;em&gt;. The devil is in the details, so writing less, makes him &lt;em&gt;easier to spot&lt;&#x2F;em&gt;. Plus, every line you write, somebody else or even you have to read and understand &lt;em&gt;over and over&lt;&#x2F;em&gt; again.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;legacy&quot;&gt;Legacy&lt;&#x2F;h2&gt;
&lt;p&gt;Months or years after, the solution gets outdated, still it works. A possible sceneario could be in terms of the &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Pareto_principle?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;Pareto principle&lt;&#x2F;a&gt;, that only twenty percent of the code base is needed for 80 percent of the business use cases. So why don&#x27;t refactor? Maybe you have to get feature complete for the next release and the sales team keeps saying that only new features sell. But also on the engineering side, of course, working on new features is more fun. We need to get the priorities right. If the error handling or monitoring code for critical functionality became cryptic and untrusted over the years, you should decide slowly about refactoring it or not. Legacy code tells a story. Maybe a good, maybe a bad one. Most importantly, we should have learned something useful in retrospective.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;minimalism-and-elegant-code&#x2F;%7Bfilename%7D&#x2F;images&#x2F;minimalismcode4.jpg&quot; alt=&quot;Working on Design&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;We all know that technical debt can be a big burden, it slows down the development cycle, scares off new employees, scares off old employees, seriously, nobody wants a share of that old pie. Even when this old pie is still making money, even when it looks shiny and new. Removing code makes space for better, more suitable and elegant code. Even if it might feel like it, it is not equivalent of burning money or business value, see &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Sunk_costs?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;Sunk cost fallacy&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experience-over-lines-of-code&quot;&gt;Experience over Lines of Code&lt;&#x2F;h2&gt;
&lt;p&gt;The real value is in the heads of the people who worked on it. Programming is mind work, and writing code is not only translating the requirements into code, it is creative work which involves the experience in coming up with a precise design: More efficient, and also simpler to understand. Think about what is actually needed, here and now, not what was needed in the past or will be needed in the future (&lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;You_aren&amp;#x27;t_gonna_need_it?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;YAGNI - you arent gonna need it&lt;&#x2F;a&gt;), you might want to write minimal code which only fits required functionality, not more - not less.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;striving-towards-elegance&quot;&gt;Striving towards Elegance&lt;&#x2F;h2&gt;
&lt;p&gt;Of course, you should not forget about the principles of writing clean code: Design patterns, test-driven development, continous integration, abstraction principle and so on. Having a good test coverage will help you a lot getting rid of bloated or even unused code. I strongly believe, that striving towards elegant design is a very important trait every good engineer or programmer should have or should develop to excel in her or his profession. Similiar to &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Occam&amp;#x27;s_razor?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;Occam’s Razor&lt;&#x2F;a&gt; of chosing the hypothesis with the least assumptions, we should write minimal code without &lt;a rel=&quot;noopener&quot; target=&quot;_blank&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Code_bloat?utm_source=madewithtea&amp;amp;utm_medium=blog&amp;amp;utm_campaign=minimalism-and-elegant-code&quot;&gt;code bloat&lt;&#x2F;a&gt;, otherwise it fails to work, is hard to use, hard to maintain, and is less applicable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;emptiness&quot;&gt;Emptiness&lt;&#x2F;h2&gt;
&lt;p&gt;Let me give you another perspective, which came into my mind. I will start explaining it for the minimalism lifestyle. By buying stuff or gaining attachments you remove emptiness in your life. You need the extra time to maintain and spare attention to these things which are nice to have but not ultimately important for you, like a second car, second bicycle, or whatever crosses your mind now. On the contrary, emptiness does not need to be maintained, and you would have more time for significant parts of your life. Shifting the perspective to code: While writing code, you remove emptiness. And emptiness does not need to be maintained. Emptiness can be seen as a reservoir or budget of time. Hence, if you remove too much emptiness, you end up having legacy code you are not able to maintain in time while also writing new code.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;www.madewithtea.com&#x2F;posts&#x2F;minimalism-and-elegant-code&#x2F;%7Bfilename%7D&#x2F;images&#x2F;minimalismcode3.jpg&quot; alt=&quot;Empty Desk&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;last-words&quot;&gt;Last Words&lt;&#x2F;h2&gt;
&lt;p&gt;In my opinion, the principle of elegant code should be taught in lesson one of programming. It is simple but powerful like minimalism, the life-changing trait, itself. I hope this article will fire up your motivation of thinking smart, writing less and reflecting on requirements and code. But keep in mind, that nothing will change, until you respect and integrate it into your daily working routine. Therefore I am glad that we cultivate this attitude on a daily basis at work. Spread the article if you like it and let us discuss the idea.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
