<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kamal Rhrabla</title>
    <description>The latest articles on DEV Community by Kamal Rhrabla (@ghrabla).</description>
    <link>https://dev.to/ghrabla</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F907424%2Fa0a665a3-53e6-4cb1-a582-811270be8c27.jpeg</url>
      <title>DEV Community: Kamal Rhrabla</title>
      <link>https://dev.to/ghrabla</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ghrabla"/>
    <language>en</language>
    <item>
      <title>How Traveling Shaped My Mind and Helped Me Respect Other Cultures</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Wed, 27 May 2026 19:21:07 +0000</pubDate>
      <link>https://dev.to/ghrabla/how-traveling-shaped-my-mind-and-helped-me-respect-other-cultures-2c5k</link>
      <guid>https://dev.to/ghrabla/how-traveling-shaped-my-mind-and-helped-me-respect-other-cultures-2c5k</guid>
      <description>&lt;p&gt;Traveling is more than moving from one place to another. It is not only about seeing new places, taking pictures, or trying different foods. For me, traveling has been one of the most important experiences in shaping my psychological thinking, widening my perspective, and teaching me how to respect other people’s cultures.&lt;/p&gt;

&lt;p&gt;When you travel, you do not only discover the world, you also discover yourself. You learn how people live differently, think differently, eat differently, and express themselves differently. This helps you become more open-minded, more understanding, and more human.&lt;/p&gt;

&lt;h2&gt;
  
  
  Traveling and psychological growth
&lt;/h2&gt;

&lt;p&gt;One of the biggest benefits of traveling is psychological growth. When a person stays in only one environment for too long, it is easy to think that their way of living is the normal or correct way. But traveling teaches the opposite. It teaches that there are many ways to live a meaningful life.&lt;/p&gt;

&lt;p&gt;Travel helps a person become mentally flexible. It challenges assumptions, reduces narrow thinking, and builds empathy. You begin to understand that culture shapes behavior, values, traditions, and even communication styles. Instead of judging differences, you begin to appreciate them.&lt;/p&gt;

&lt;p&gt;Traveling also helps build confidence and independence. When you visit new places, adapt to unfamiliar situations, and communicate with different people, your mind becomes stronger. You become better at observing, learning, and adjusting. These experiences improve not only knowledge, but also emotional intelligence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learning respect through culture
&lt;/h2&gt;

&lt;p&gt;Respecting other cultures is one of the most valuable lessons travel can teach. Every country and every city has its own traditions, food, social rules, and way of life. When we travel with curiosity and respect, we stop seeing difference as something strange. We start seeing it as something beautiful.&lt;/p&gt;

&lt;p&gt;Culture is not something to compare in order to decide which is better. It is something to understand. By meeting people from different backgrounds, we learn that values such as kindness, hospitality, family, and community can exist everywhere, even if they are expressed differently.&lt;/p&gt;

&lt;p&gt;Travel taught me that respect begins with listening and observing. It means entering another place with humility, not superiority. It means learning from people instead of assuming we already know enough.&lt;/p&gt;

&lt;h2&gt;
  
  
  My experience with external traveling
&lt;/h2&gt;

&lt;p&gt;Traveling outside Morocco expanded my thinking even more. Visiting Thailand, Malaysia, and Saudi Arabia helped me understand the world from a broader perspective.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thailand
&lt;/h3&gt;

&lt;p&gt;Thailand left a strong impression on me because of its beauty, culture, and atmosphere. The nature there is remarkable, with tropical landscapes, beaches, and a relaxing environment. The food culture is also very rich and memorable. Thai food is known for its strong flavors, balance, and creativity. Experiencing their food showed me how deeply culture can be expressed through taste.&lt;/p&gt;

&lt;p&gt;What I also appreciated in Thailand was the calmness and kindness often shown in social interactions. It made me reflect on the importance of respect, politeness, and peaceful coexistence.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Malaysia
&lt;/h3&gt;

&lt;p&gt;Malaysia gave me a strong sense of multicultural harmony. It is a country where different cultures, religions, and communities exist together in a visible way. That was very meaningful to me. It showed me that diversity can be a source of strength.&lt;/p&gt;

&lt;p&gt;The food in Malaysia was another important part of the experience. It reflects a blend of cultural influences, which makes it rich and varied. The natural landscapes, urban development, and cultural diversity together made the country feel dynamic and educational.&lt;/p&gt;

&lt;p&gt;Traveling there made me think more about coexistence and how societies can be shaped by openness and exchange.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Saudi Arabia
&lt;/h3&gt;

&lt;p&gt;Saudi Arabia gave me a different kind of experience, one that felt deeply connected to tradition, religion, and identity. The culture there carries strong values related to family, faith, and hospitality. Visiting Saudi Arabia helped me better understand a society where tradition plays a central role in daily life.&lt;/p&gt;

&lt;p&gt;The food, clothing, social manners, and environment all reflected a strong cultural identity. This experience reminded me that every country has its own rhythm and logic. Understanding that helps a person become less judgmental and more respectful.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  My experience with internal traveling in Morocco
&lt;/h2&gt;

&lt;p&gt;Since I was a child, I had the chance to travel inside Morocco, and these experiences had a big impact on me. Morocco itself is a country full of diversity. Each city has its own atmosphere, identity, and cultural beauty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merzouga
&lt;/h3&gt;

&lt;p&gt;Traveling to Merzouga gave me a special connection with nature. The desert has a unique silence that makes a person reflect deeply. The golden dunes, the open sky, and the peaceful atmosphere create a different kind of thinking. In Merzouga, I felt the beauty of simplicity. Life there teaches patience, calmness, and appreciation for natural beauty.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhkz2nu7654lvy3gnevl.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffhkz2nu7654lvy3gnevl.jpeg" alt=" " width="576" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Marrakech
&lt;/h3&gt;

&lt;p&gt;Marrakech showed me energy, color, and tradition. The city is full of life, from its markets to its architecture. The food, the people, the movement, and the historical feeling of the city make it unforgettable. Marrakech taught me how culture can be alive in everyday life. It is a place where tradition and activity meet in a powerful way.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Chefchaouen
&lt;/h3&gt;

&lt;p&gt;Chefchaouen gave me a feeling of calm and simplicity. The blue streets, the mountains around the city, and the peaceful atmosphere make it feel different from anywhere else. Walking through its small alleys feels relaxing and timeless. The city taught me that beauty does not always need noise or speed. Chefchaouen is a place where nature, color, and peace exist together in harmony.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Essaouira
&lt;/h3&gt;

&lt;p&gt;Essaouira showed me freedom, art, and the spirit of the ocean. The sound of the waves, the old medina, and the windy streets create a unique atmosphere full of creativity and history. The city feels both traditional and open to the world at the same time. Essaouira taught me how a place can stay calm while still being full of life and inspiration.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Rabat
&lt;/h3&gt;

&lt;p&gt;Rabat gave me a different impression. It feels organized, calm, and elegant. As the capital of Morocco, it reflects both history and modernity. Traveling there helped me see another side of Moroccan identity, one that is political, intellectual, and balanced. It made me appreciate the variety that exists even within one country.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Tangier
&lt;/h3&gt;

&lt;p&gt;Tangier felt unique because of its geographic and cultural position. It has a special charm, influenced by both Moroccan and international history. The sea, the atmosphere, and the cultural richness of Tangier gave me the feeling of openness. It is a city that naturally connects worlds, and that made me think more about how cultures meet and influence each other.&lt;/p&gt;

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

&lt;p&gt;Through traveling in Morocco from childhood, I learned that even inside one country, people live in different ways. Their accents, habits, foods, and environments may change from one city to another. This taught me early in life to respect diversity and to stay curious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Food, nature, and the human connection
&lt;/h2&gt;

&lt;p&gt;One of the most beautiful parts of traveling is how food and nature become ways of understanding people. Food is not just something we eat, it carries memory, history, and identity. Every dish tells a story about the land, the climate, and the traditions of a place.&lt;/p&gt;

&lt;p&gt;Nature also changes the way we think and feel. Deserts, seas, mountains, forests, and cities all affect the human mind differently. Traveling through these environments helps us feel the variety of life more deeply.&lt;/p&gt;

&lt;p&gt;When I think about Morocco, Thailand, Malaysia, and Saudi Arabia, I do not only remember places. I remember feelings, colors, flavors, conversations, and lessons. That is what makes travel powerful.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Traveling has helped me grow not only as a person who sees the world, but as a person who understands it more deeply. It improved my psychological thinking by making me more open-minded, adaptable, and respectful of other cultures. It taught me that differences are not barriers, they are opportunities to learn.&lt;/p&gt;

&lt;p&gt;My external travels to Thailand, Malaysia, and Saudi Arabia expanded my vision and helped me understand the richness of global cultures. My internal travels in Morocco, from Merzouga to Marrakech, Rabat, and Tangier, taught me to appreciate diversity within my own country.&lt;/p&gt;

&lt;p&gt;In the end, travel is one of the best teachers. It teaches respect, humility, curiosity, and human connection. And most importantly, it reminds us that no matter how different people may seem, there is always something valuable we can learn from one another.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>mentalhealth</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How Some Books Shaped My Way of Thinking</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Wed, 27 May 2026 19:12:49 +0000</pubDate>
      <link>https://dev.to/ghrabla/how-some-books-shaped-my-way-of-thinking-4mjf</link>
      <guid>https://dev.to/ghrabla/how-some-books-shaped-my-way-of-thinking-4mjf</guid>
      <description>&lt;p&gt;Some books entertain you for a few days. Others quietly reorganize the way you see yourself, your work, and your future. For me, &lt;em&gt;Atomic Habits&lt;/em&gt; by James Clear, &lt;em&gt;Deep Work&lt;/em&gt; by Cal Newport, and &lt;em&gt;The Mountain Is You&lt;/em&gt; by Brianna Wiest are three of those books.&lt;/p&gt;

&lt;p&gt;Each one helped me in a different way. Together, they changed how I think about growth, discipline, focus, and self-sabotage. They did not just give me advice. They gave me frameworks. And once you have a better framework, your choices start to change naturally.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;em&gt;Atomic Habits&lt;/em&gt; taught me that small actions shape identity
&lt;/h2&gt;

&lt;p&gt;Before reading &lt;em&gt;Atomic Habits&lt;/em&gt;, it was easy to think of improvement as something dramatic. I thought change had to feel big to matter. James Clear helped me understand the opposite: real change often begins in tiny, repeatable actions.&lt;/p&gt;

&lt;p&gt;The most powerful idea from the book is that habits are not just about results — they are about identity. Every repeated action is a vote for the kind of person you want to become. That idea changed my thinking because it moved me away from chasing motivation and toward building proof.&lt;/p&gt;

&lt;p&gt;Instead of saying, “I want to be productive,” I started thinking, “What would a productive person do today?”&lt;br&gt;
Instead of saying, “I want to be healthier,” I started asking, “What small habit would reinforce that identity?”&lt;/p&gt;

&lt;p&gt;This way of thinking feels more realistic and more sustainable. It removes the pressure of instant transformation and replaces it with consistency. It helped me realize that success is rarely one giant decision. More often, it is the outcome of many small decisions repeated over time.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. &lt;em&gt;Deep Work&lt;/em&gt; taught me that focus is a skill, not just a mood
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Deep Work&lt;/em&gt; helped me see how much modern life trains distraction. It is easy to stay busy all day and still avoid meaningful progress. Cal Newport makes a strong distinction between shallow work and deep work. Shallow work keeps you occupied. Deep work creates real value.&lt;/p&gt;

&lt;p&gt;This book changed my mindset by showing me that concentration should be trained and protected. I stopped thinking of focus as something that appears when I “feel like it.” Instead, I began to see it as a discipline.&lt;/p&gt;

&lt;p&gt;That shift matters a lot. When you treat focus like a skill, you stop waiting for perfect conditions. You start creating them. You protect your time, reduce distractions, and make space for serious thought.&lt;/p&gt;

&lt;p&gt;Because of this book, I think more carefully about where my attention goes. Attention is not a small thing. It shapes output, learning, and even confidence. When I can focus deeply on one thing, I feel more capable, more calm, and more in control of my direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. &lt;em&gt;The Mountain Is You&lt;/em&gt; taught me that the real challenge is often internal
&lt;/h2&gt;

&lt;p&gt;While &lt;em&gt;Atomic Habits&lt;/em&gt; focuses on behavior and &lt;em&gt;Deep Work&lt;/em&gt; focuses on attention, &lt;em&gt;The Mountain Is You&lt;/em&gt; goes deeper into the emotional side of growth. Its main message is powerful: many of our biggest obstacles are not external. They come from within.&lt;/p&gt;

&lt;p&gt;That idea forced me to think differently about self-sabotage. Sometimes procrastination is not laziness. Sometimes inconsistency is not lack of ability. Sometimes fear, unresolved emotions, or limiting beliefs are quietly shaping behavior.&lt;/p&gt;

&lt;p&gt;This book helped me become more honest with myself. Instead of only asking, “Why am I not doing better?” I started asking, “What part of me is resisting change, and why?”&lt;/p&gt;

&lt;p&gt;That question changes everything. It encourages self-awareness instead of self-judgment. It reminds me that growth is not only about pushing harder. Sometimes it is about healing, understanding, and letting go of patterns that no longer serve you.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. How these books work together
&lt;/h2&gt;

&lt;p&gt;What makes these three books especially powerful is how well they connect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Atomic Habits&lt;/em&gt; teaches me &lt;strong&gt;how to build better systems&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Deep Work&lt;/em&gt; teaches me &lt;strong&gt;how to protect my attention and produce meaningful work&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Mountain Is You&lt;/em&gt; teaches me &lt;strong&gt;how to understand the inner resistance that gets in the way&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, they create a fuller picture of personal growth.&lt;/p&gt;

&lt;p&gt;One book says: start small and stay consistent.&lt;br&gt;&lt;br&gt;
Another says: focus deeply on what matters.&lt;br&gt;&lt;br&gt;
The third says: understand yourself well enough to stop becoming your own obstacle.&lt;/p&gt;

&lt;p&gt;That combination has helped my way of thinking become more intentional. I now think less about overnight success and more about daily structure. I think less about being constantly busy and more about being deeply effective. I think less about blaming circumstances and more about understanding my own patterns.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. How they changed my mindset in everyday life
&lt;/h2&gt;

&lt;p&gt;These books influenced me beyond reading. They affect how I approach normal days.&lt;/p&gt;

&lt;h3&gt;
  
  
  Discipline
&lt;/h3&gt;

&lt;p&gt;I no longer see discipline as punishment. I see it as a way of making life easier. Good habits reduce decision fatigue. Focus reduces chaos. Self-awareness reduces repeated mistakes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Progress
&lt;/h3&gt;

&lt;p&gt;I have become more patient with growth. Small improvements matter. Quiet work matters. Internal change matters. Not every breakthrough looks impressive in the moment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-awareness
&lt;/h3&gt;

&lt;p&gt;I now pay more attention to what triggers avoidance, distraction, or inconsistency. That awareness helps me respond better instead of reacting automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Personal responsibility
&lt;/h3&gt;

&lt;p&gt;These books helped me take more ownership of my life. Not in a harsh way, but in an empowering way. They remind me that while I cannot control everything, I can control many of my systems, choices, and responses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Atomic Habits&lt;/em&gt;, &lt;em&gt;Deep Work&lt;/em&gt;, and &lt;em&gt;The Mountain Is You&lt;/em&gt; each gave me a different lens for understanding growth. One taught me the power of small repeated actions. One taught me the value of intense focus. One taught me to confront the internal struggles that shape behavior.&lt;/p&gt;

&lt;p&gt;Together, they helped me think in a more mature and constructive way. They made me more intentional, more reflective, and more aware that real change happens both externally and internally.&lt;/p&gt;

&lt;p&gt;If I had to summarize their impact in one sentence, I would say this: they taught me that becoming better is not about forcing a new life overnight — it is about building better habits, protecting deeper focus, and understanding yourself enough to stop standing in your own way.&lt;/p&gt;

</description>
      <category>learning</category>
      <category>mentalhealth</category>
      <category>productivity</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>How Space Made Me Love Technology</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Tue, 26 May 2026 18:48:25 +0000</pubDate>
      <link>https://dev.to/ghrabla/how-space-made-me-love-technology-2nfp</link>
      <guid>https://dev.to/ghrabla/how-space-made-me-love-technology-2nfp</guid>
      <description>&lt;p&gt;When I was a child, my uncle gave me a book about the cosmos, the planets, and the great mysteries of space.&lt;/p&gt;

&lt;p&gt;At that age, I could not fully understand the science behind what I was reading. I did not know how gravity worked, how planets moved, or why the universe seemed so vast and endless. But even without understanding the details, something inside me changed forever.&lt;/p&gt;

&lt;p&gt;I still remember spending long hours turning the pages of that book, staring at the images of planets, stars, and galaxies. Every page felt like an invitation to imagine a world far beyond my own. I would look at the illustrations and wonder what existed beyond Earth, beyond the Moon, and beyond everything I could see in the night sky.&lt;/p&gt;

&lt;p&gt;Among all the planets, &lt;strong&gt;Uranus&lt;/strong&gt; was always the one that fascinated me the most. Maybe it was its mysterious blue color, its incredible distance from the Sun, or simply the fact that it seemed so different from the others. To me, Uranus felt silent, cold, and unknown, like a hidden world waiting patiently to be discovered and understood.&lt;/p&gt;

&lt;p&gt;Looking back now, I believe that book was one of the first reasons I became deeply interested in technology and science. It planted a question in my mind that never truly disappeared: &lt;em&gt;How do humans understand things so far away from us?&lt;/em&gt; That question slowly became curiosity, and curiosity eventually became passion.&lt;/p&gt;

&lt;p&gt;As I grew older, I began learning more about astronomy, rockets, astronauts, satellites, and the extraordinary engineering behind space exploration. The more I learned, the more amazed I became. Space was no longer just about beautiful planets or distant stars. It became a story of human intelligence, persistence, and imagination.&lt;/p&gt;

&lt;p&gt;What fascinated me most was not only the astronauts, but also the thousands of people behind them.&lt;/p&gt;

&lt;p&gt;When people think about space missions, they often imagine the astronauts standing at the center of history. But behind every launch, every landing, and every moment of success, there are teams of engineers, scientists, mathematicians, programmers, and technicians working together with precision and dedication. That realization changed the way I saw technology.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Apollo missions&lt;/strong&gt;, for example, were not only about reaching the Moon.&lt;/p&gt;

&lt;p&gt;They were about collaboration.&lt;/p&gt;

&lt;p&gt;They were about discipline, mathematics, engineering, communication, and belief.&lt;/p&gt;

&lt;p&gt;Inside Houston’s mission control center, countless professionals worked together toward one final objective: landing human beings on the Moon and bringing them safely back to Earth. Every calculation mattered. Every system mattered. Every person mattered.&lt;/p&gt;

&lt;p&gt;Even today, it still feels almost unreal to think about what humanity achieved during that era.&lt;/p&gt;

&lt;p&gt;One of the most unforgettable moments in history came with the words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Houston, Tranquility Base here. The Eagle has landed.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That sentence captured the success of years of effort, sacrifice, and innovation. It was not only a message from the Moon, it was proof that human beings could turn an impossible dream into reality.&lt;/p&gt;

&lt;p&gt;And then came the moment that inspired millions of people around the world:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“That’s one small step for man, one giant leap for mankind.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Neil Armstrong’s words represented far more than a person walking on the Moon. They represented the power of curiosity guided by knowledge, and the power of technology guided by vision.&lt;/p&gt;

&lt;p&gt;As a child, watching astronauts, rockets, and space documentaries made me realize something important: &lt;strong&gt;technology is not just about machines or computers&lt;/strong&gt;. Technology is imagination transformed into reality. It is the bridge between an idea and an achievement.&lt;/p&gt;

&lt;p&gt;Behind every rocket launch, there were people solving problems no one had solved before. There were programmers writing systems, engineers designing machines, mathematicians checking trajectories, and teams making decisions under pressure. These were people who dedicated years of their lives to make the impossible possible.&lt;/p&gt;

&lt;p&gt;I think this is one of the reasons I became so passionate about technology and software engineering.&lt;/p&gt;

&lt;p&gt;For me, technology has always been more than code, devices, or systems. It is a human effort to create, improve, and explore. It is a way of turning curiosity into progress.&lt;/p&gt;

&lt;p&gt;Today, whenever I learn something new about programming, systems, or engineering, I still remember that child sitting with a book of planets and dreaming about space. I remember the wonder I felt, the questions I asked, and the excitement of discovering something bigger than myself.&lt;/p&gt;

&lt;p&gt;That feeling never completely disappeared.&lt;/p&gt;

&lt;p&gt;And maybe that is the most beautiful part of it all: sometimes, a simple childhood memory can shape an entire future.&lt;/p&gt;

</description>
      <category>devjournal</category>
      <category>learning</category>
      <category>science</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Using Google Cloud Storage as an S3 Alternative (AWS S3 --&gt; GCS Guide)</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Mon, 20 Apr 2026 00:36:36 +0000</pubDate>
      <link>https://dev.to/ghrabla/using-google-cloud-storage-as-an-s3-alternative-aws-s3-gcs-guide-1ldo</link>
      <guid>https://dev.to/ghrabla/using-google-cloud-storage-as-an-s3-alternative-aws-s3-gcs-guide-1ldo</guid>
      <description>&lt;p&gt;If you’re coming from AWS, &lt;strong&gt;Amazon S3&lt;/strong&gt; is usually the default choice for object storage. On Google Cloud, the direct equivalent is &lt;strong&gt;Google Cloud Storage (GCS)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This article explains how to think about GCS if you already know S3, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Concept mapping (bucket/object/policy)&lt;/li&gt;
&lt;li&gt;Common features (versioning, lifecycle, encryption)&lt;/li&gt;
&lt;li&gt;Access control (IAM vs ACLs)&lt;/li&gt;
&lt;li&gt;Signed URLs (pre-signed URLs equivalent)&lt;/li&gt;
&lt;li&gt;A small hands-on walkthrough with &lt;code&gt;gcloud&lt;/code&gt; (and optional &lt;code&gt;gsutil&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  1) Quick mapping: S3 concepts → GCS concepts
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AWS S3&lt;/th&gt;
&lt;th&gt;Google Cloud Storage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Bucket&lt;/td&gt;
&lt;td&gt;Bucket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Object&lt;/td&gt;
&lt;td&gt;Object&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prefix / “folder”&lt;/td&gt;
&lt;td&gt;Object name prefix (folders are virtual)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Versioning&lt;/td&gt;
&lt;td&gt;Object Versioning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Lifecycle Rules&lt;/td&gt;
&lt;td&gt;Lifecycle Management&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bucket Policy / IAM&lt;/td&gt;
&lt;td&gt;Cloud IAM policies (preferred)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ACLs&lt;/td&gt;
&lt;td&gt;ACLs (supported, but often discouraged)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSE-S3 / SSE-KMS&lt;/td&gt;
&lt;td&gt;Google-managed encryption / CMEK (Cloud KMS)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-signed URL&lt;/td&gt;
&lt;td&gt;Signed URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 Event Notifications&lt;/td&gt;
&lt;td&gt;Pub/Sub Notifications + Eventarc (common patterns)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Mental model:&lt;/strong&gt; GCS is object storage like S3: you store objects in buckets, and you control access with policy.&lt;/p&gt;




&lt;h2&gt;
  
  
  2) Why choose GCS over S3?
&lt;/h2&gt;

&lt;p&gt;You might choose GCS when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your workloads already run on &lt;strong&gt;GCP&lt;/strong&gt; (Cloud Run, GKE, Compute Engine)&lt;/li&gt;
&lt;li&gt;You want tight integration with &lt;strong&gt;IAM&lt;/strong&gt;, &lt;strong&gt;Cloud KMS&lt;/strong&gt;, &lt;strong&gt;Cloud Logging&lt;/strong&gt;, &lt;strong&gt;BigQuery&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You need a clean path to analytics or pipelines (e.g., GCS → BigQuery/Dataflow)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You might stick with S3 when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your ecosystem is primarily AWS-based&lt;/li&gt;
&lt;li&gt;You heavily rely on S3-specific features or tooling already standardized in your org&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3) Create a bucket (the GCS way)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pick a naming + location strategy
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Bucket names are &lt;strong&gt;globally unique&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;You choose a &lt;strong&gt;location type&lt;/strong&gt; (region / dual-region / multi-region)&lt;/li&gt;
&lt;li&gt;You can also choose a &lt;strong&gt;storage class&lt;/strong&gt; (Standard, Nearline, Coldline, Archive)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create a bucket with &lt;code&gt;gcloud&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Replace placeholders and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;PROJECT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-project-id"&lt;/span&gt;
&lt;span class="nv"&gt;BUCKET_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-unique-bucket-name"&lt;/span&gt;
&lt;span class="nv"&gt;LOCATION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"us-central1"&lt;/span&gt;

gcloud storage buckets create gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PROJECT_ID&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--location&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$LOCATION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you used &lt;code&gt;aws s3 mb s3://...&lt;/code&gt;, this is the equivalent.&lt;/p&gt;




&lt;h2&gt;
  
  
  4) Upload, download, list objects
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Upload a file
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"hello gcs"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; hello.txt

gcloud storage &lt;span class="nb"&gt;cp &lt;/span&gt;hello.txt gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt;/hello.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  List objects
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage &lt;span class="nb"&gt;ls &lt;/span&gt;gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Download the object
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;hello.txt
gcloud storage &lt;span class="nb"&gt;cp &lt;/span&gt;gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt;/hello.txt hello.txt
&lt;span class="nb"&gt;cat &lt;/span&gt;hello.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5) Access control: IAM vs ACLs (S3 users pay attention here)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The recommended approach: IAM + Uniform bucket-level access
&lt;/h3&gt;

&lt;p&gt;On GCS, the modern best practice is typically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;strong&gt;IAM&lt;/strong&gt; for access control&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Uniform bucket-level access&lt;/strong&gt; (UBLA)&lt;/li&gt;
&lt;li&gt;Avoid object-level ACL complexity unless you really need it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enable UBLA:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage buckets update gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt; &lt;span class="nt"&gt;--uniform-bucket-level-access&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then grant permissions using IAM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: grant read-only access to a user for a bucket
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;USER_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"dev@example.com"&lt;/span&gt;

gcloud storage buckets add-iam-policy-binding gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--member&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"user:&lt;/span&gt;&lt;span class="nv"&gt;$USER_EMAIL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"roles/storage.objectViewer"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;S3 analogy:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is closer to controlling access via IAM policy rather than relying on object ACLs.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  6) Public buckets: how to do it (and how to avoid accidents)
&lt;/h2&gt;

&lt;p&gt;Public access is often a footgun. If your goal is “public website assets,” consider using:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud Storage + Cloud CDN (or a load balancer) depending on needs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you &lt;em&gt;do&lt;/em&gt; need public read access, do it intentionally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make objects publicly readable (example)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage buckets add-iam-policy-binding gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--member&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"allUsers"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"roles/storage.objectViewer"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this feels similar to an S3 bucket policy allowing &lt;code&gt;s3:GetObject&lt;/code&gt; for &lt;code&gt;"Principal": "*"&lt;/code&gt;, it is.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; For production, pair this with guardrails:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Organization policies&lt;/li&gt;
&lt;li&gt;Security reviews&lt;/li&gt;
&lt;li&gt;Logging + alerting&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  7) Signed URLs: the “pre-signed URL” equivalent
&lt;/h2&gt;

&lt;p&gt;Signed URLs are a common pattern when you want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Users to &lt;strong&gt;download&lt;/strong&gt; private objects without logging in&lt;/li&gt;
&lt;li&gt;Users to &lt;strong&gt;upload&lt;/strong&gt; directly to storage without exposing service credentials&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generate a signed URL (example)
&lt;/h3&gt;

&lt;p&gt;There are multiple ways to do this on GCP (CLI, libraries, service accounts).&lt;br&gt;
A typical pattern is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use a service account with permission to sign URLs&lt;/li&gt;
&lt;li&gt;Generate a URL with an expiration time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want, tell me your stack (Node.js / Python / Go) and I’ll add a copy/paste snippet to generate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Signed download URLs&lt;/li&gt;
&lt;li&gt;Signed upload URLs (PUT/POST)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  8) Lifecycle rules: manage cost like S3 lifecycle policies
&lt;/h2&gt;

&lt;p&gt;Lifecycle rules help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete objects older than N days&lt;/li&gt;
&lt;li&gt;Move objects to cheaper classes after N days&lt;/li&gt;
&lt;li&gt;Clean up incomplete uploads (S3 concept; in GCS you typically manage temp objects differently)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Example lifecycle JSON (delete after 30 days)
&lt;/h3&gt;

&lt;p&gt;Create a file named &lt;code&gt;lifecycle.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"rule"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Delete"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"condition"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"age"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage buckets update gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt; &lt;span class="nt"&gt;--lifecycle-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;lifecycle.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  9) Versioning: protect against accidental overwrites
&lt;/h2&gt;

&lt;p&gt;Enable object versioning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gcloud storage buckets update gs://&lt;span class="nv"&gt;$BUCKET_NAME&lt;/span&gt; &lt;span class="nt"&gt;--versioning&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is very similar to enabling S3 Versioning: you keep older generations of objects when overwritten/deleted (depending on lifecycle/retention settings).&lt;/p&gt;




&lt;h2&gt;
  
  
  10) Encryption: default vs customer-managed keys (CMEK)
&lt;/h2&gt;

&lt;p&gt;By default, GCS encrypts data at rest. If you need tighter control (compliance, audit, key rotation requirements), you can use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;CMEK&lt;/strong&gt; with &lt;strong&gt;Cloud KMS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This resembles S3 SSE-KMS.&lt;/p&gt;

&lt;p&gt;If you want, I can write a follow-up post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“GCS + Cloud KMS (CMEK) step-by-step”&lt;/li&gt;
&lt;li&gt;including least-privilege IAM for the KMS key&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  11) Logging and auditing (don’t skip this)
&lt;/h2&gt;

&lt;p&gt;For production:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure you understand &lt;strong&gt;Cloud Audit Logs&lt;/strong&gt; for storage access&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Cloud Logging&lt;/strong&gt; to track access patterns&lt;/li&gt;
&lt;li&gt;Add alerts for suspicious behavior (e.g., many deletes, access from unexpected identities)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  12) Common pitfalls for S3 users moving to GCS
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Bucket names are global&lt;/strong&gt; (same as S3), so naming can be frustrating—plan ahead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;“Folders” aren’t real&lt;/strong&gt; (same as S3). Everything is just object prefixes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IAM vs ACLs&lt;/strong&gt;: don’t mix unless you know why—prefer UBLA + IAM.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public access&lt;/strong&gt; is easy to misconfigure—avoid “quick public” in real systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Costs&lt;/strong&gt; depend on storage class, operations, and egress—use lifecycle rules early.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;If you know S3, you already understand 80% of GCS. The biggest shift is usually &lt;strong&gt;access control&lt;/strong&gt;: on GCP, you’ll typically standardize on &lt;strong&gt;IAM + Uniform bucket-level access&lt;/strong&gt;, plus signed URLs for controlled sharing.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>google</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Terraform Modules for Reusable GCP Infrastructure (With a Real VPC Module Example)</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Sat, 18 Apr 2026 19:01:16 +0000</pubDate>
      <link>https://dev.to/ghrabla/terraform-modules-for-reusable-gcp-infrastructure-with-a-real-vpc-module-example-4b</link>
      <guid>https://dev.to/ghrabla/terraform-modules-for-reusable-gcp-infrastructure-with-a-real-vpc-module-example-4b</guid>
      <description>&lt;p&gt;Terraform modules are the best way to stop copy/pasting infrastructure code across projects and environments. Instead of rewriting the same VPC, subnets, firewall rules, and settings over and over, you wrap that logic in a &lt;strong&gt;module&lt;/strong&gt; and reuse it with clean inputs/outputs.&lt;/p&gt;

&lt;p&gt;This post shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What a module is (in practice)&lt;/li&gt;
&lt;li&gt;How to structure modules in a repo&lt;/li&gt;
&lt;li&gt;How to write a &lt;strong&gt;reusable GCP VPC module&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;How to call it for &lt;strong&gt;dev&lt;/strong&gt; and &lt;strong&gt;prod&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Common module mistakes (and how to avoid them)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What is a Terraform module?
&lt;/h2&gt;

&lt;p&gt;A Terraform module is just a folder containing Terraform files (&lt;code&gt;.tf&lt;/code&gt;) that expose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;inputs&lt;/strong&gt; (&lt;code&gt;variables.tf&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;outputs&lt;/strong&gt; (&lt;code&gt;outputs.tf&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;resources&lt;/strong&gt; (&lt;code&gt;main.tf&lt;/code&gt;, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can call a module multiple times with different parameters, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"network_dev"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"../modules/vpc"&lt;/span&gt;
  &lt;span class="nx"&gt;project_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"my-dev-project"&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_name&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-vpc"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Recommended repository structure
&lt;/h2&gt;

&lt;p&gt;Here’s a clean layout that works well for real teams:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform/
  modules/
    vpc/
      main.tf
      variables.tf
      outputs.tf
      versions.tf
      README.md
  envs/
    dev/
      main.tf
      providers.tf
      backend.tf
      terraform.tfvars
    prod/
      main.tf
      providers.tf
      backend.tf
      terraform.tfvars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Idea:&lt;/strong&gt; keep &lt;strong&gt;modules generic&lt;/strong&gt; and &lt;strong&gt;environments thin&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Module example: a reusable GCP VPC module
&lt;/h2&gt;

&lt;p&gt;This VPC module will create:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 VPC network&lt;/li&gt;
&lt;li&gt;N subnets (from a list)&lt;/li&gt;
&lt;li&gt;Optional firewall rules (basic example)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;modules/vpc/versions.tf&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.5.0"&lt;/span&gt;

  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;google&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/google"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 5.0.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;modules/vpc/variables.tf&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"project_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"GCP project ID where resources will be created."&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"vpc_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Name of the VPC."&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"routing_mode"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"VPC routing mode: REGIONAL or GLOBAL."&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;default&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"REGIONAL"&lt;/span&gt;

  &lt;span class="nx"&gt;validation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;condition&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"REGIONAL"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"GLOBAL"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;routing_mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;error_message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"routing_mode must be REGIONAL or GLOBAL."&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"subnets"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOT&lt;/span&gt;&lt;span class="sh"&gt;
List of subnets to create.

Example:
[
  { name="public-us-central1", region="us-central1", cidr="10.10.0.0/24", private_google_access=true },
  { name="private-us-central1", region="us-central1", cidr="10.10.1.0/24", private_google_access=true }
]
&lt;/span&gt;&lt;span class="no"&gt;EOT

&lt;/span&gt;  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;region&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;cidr&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;private_google_access&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;bool&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"firewall_rules"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOT&lt;/span&gt;&lt;span class="sh"&gt;
Optional firewall rules.
Keep it simple: allow protocol/ports from source ranges to target tags.
&lt;/span&gt;&lt;span class="no"&gt;EOT

&lt;/span&gt;  &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;name&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;direction&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"INGRESS"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;priority&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;optional&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;source_ranges&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;target_tags&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
    &lt;span class="nx"&gt;ports&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}))&lt;/span&gt;

  &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;modules/vpc/main.tf&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_network"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;project&lt;/span&gt;                 &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project_id&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;vpc_name&lt;/span&gt;
  &lt;span class="nx"&gt;auto_create_subnetworks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;routing_mode&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;routing_mode&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_subnetwork"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subnets&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;project&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project_id&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;                     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;ip_cidr_range&lt;/span&gt;            &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cidr&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;                   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;region&lt;/span&gt;
  &lt;span class="nx"&gt;network&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;private_ip_google_access&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;private_google_access&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"google_compute_firewall"&lt;/span&gt; &lt;span class="s2"&gt;"this"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;for_each&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firewall_rules&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;project&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project_id&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;network&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
  &lt;span class="nx"&gt;direction&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;direction&lt;/span&gt;
  &lt;span class="nx"&gt;priority&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;priority&lt;/span&gt;
  &lt;span class="nx"&gt;target_tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target_tags&lt;/span&gt;

  &lt;span class="nx"&gt;source_ranges&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;source_ranges&lt;/span&gt;

  &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;protocol&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;protocol&lt;/span&gt;
    &lt;span class="nx"&gt;ports&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ports&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;modules/vpc/outputs.tf&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"network_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"The ID of the VPC network."&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"network_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"The name of the VPC network."&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;google_compute_network&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"subnet_ids"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Subnet IDs keyed by subnet name."&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;google_compute_subnetwork&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;this&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;k&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using the module: dev environment example
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;envs/dev/main.tf&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"../../modules/vpc"&lt;/span&gt;
  &lt;span class="nx"&gt;project_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;project_id&lt;/span&gt;
  &lt;span class="nx"&gt;vpc_name&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-vpc"&lt;/span&gt;

  &lt;span class="nx"&gt;subnets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-us-central1-public"&lt;/span&gt;
      &lt;span class="nx"&gt;region&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-central1"&lt;/span&gt;
      &lt;span class="nx"&gt;cidr&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.10.0.0/24"&lt;/span&gt;
      &lt;span class="nx"&gt;private_google_access&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-us-central1-private"&lt;/span&gt;
      &lt;span class="nx"&gt;region&lt;/span&gt;                &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-central1"&lt;/span&gt;
      &lt;span class="nx"&gt;cidr&lt;/span&gt;                  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"10.10.1.0/24"&lt;/span&gt;
      &lt;span class="nx"&gt;private_google_access&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;

  &lt;span class="nx"&gt;firewall_rules&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev-allow-ssh-from-office"&lt;/span&gt;
      &lt;span class="nx"&gt;source_ranges&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"203.0.113.10/32"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;target_tags&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"ssh"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="nx"&gt;protocol&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
      &lt;span class="nx"&gt;ports&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"22"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;envs/dev/variables.tf&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"project_id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;type&lt;/span&gt;        &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Dev project ID"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Module tips (this is what saves you later)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1) Keep modules “dumb” and input-driven
&lt;/h3&gt;

&lt;p&gt;Avoid hardcoding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;regions&lt;/li&gt;
&lt;li&gt;CIDRs&lt;/li&gt;
&lt;li&gt;environment names&lt;/li&gt;
&lt;li&gt;project IDs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2) Prefer composable small modules
&lt;/h3&gt;

&lt;p&gt;Instead of a huge “platform module”, consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;modules/vpc&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;modules/cloud_run&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;modules/cloud_sql&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;modules/iam&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then compose them per environment.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Be careful with IAM resources
&lt;/h3&gt;

&lt;p&gt;Some IAM resources are &lt;strong&gt;authoritative&lt;/strong&gt; and can remove access unexpectedly.&lt;br&gt;
When in doubt, start with &lt;code&gt;*_iam_member&lt;/code&gt; resources and grow from there.&lt;/p&gt;
&lt;h3&gt;
  
  
  4) Version your modules
&lt;/h3&gt;

&lt;p&gt;If you publish modules (Git tags), you can pin versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"vpc"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"git::https://github.com/YOUR_ORG/YOUR_REPO.git//modules/vpc?ref=v1.0.0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;Terraform modules turn your GCP infrastructure into reusable building blocks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;less duplication&lt;/li&gt;
&lt;li&gt;safer changes&lt;/li&gt;
&lt;li&gt;consistent environments&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>google</category>
      <category>terraform</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Started with Google Cloud Platform (GCP): A Practical Guide for Developers</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Thu, 09 Apr 2026 22:08:22 +0000</pubDate>
      <link>https://dev.to/ghrabla/getting-started-with-google-cloud-platform-gcp-a-practical-guide-for-developers-2h23</link>
      <guid>https://dev.to/ghrabla/getting-started-with-google-cloud-platform-gcp-a-practical-guide-for-developers-2h23</guid>
      <description>&lt;p&gt;Google Cloud Platform (GCP) is Google’s suite of cloud services for building, deploying, and operating applications at scale. If you’ve used AWS or Azure, GCP will feel familiar but it also has some “Google-native” strengths like &lt;strong&gt;BigQuery&lt;/strong&gt;, first-class &lt;strong&gt;Kubernetes&lt;/strong&gt; support, and strong &lt;strong&gt;data/ML&lt;/strong&gt; tooling.&lt;/p&gt;

&lt;p&gt;This post is a developer-focused introduction: what GCP is great at, the core services you should know, and a simple path to start shipping real projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Why use GCP?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;GCP is a strong choice if you care about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managed compute that scales cleanly&lt;/strong&gt; (especially serverless)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containers + Kubernetes&lt;/strong&gt; (Google created Kubernetes)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data workloads&lt;/strong&gt; (analytics, warehousing, streaming)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Machine learning tooling&lt;/strong&gt; (MLOps, training, model hosting)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Global infrastructure + networking&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s also easy to start small (serverless) and grow into more complex architecture only when you need it.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The mental model: how GCP is organized&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Before jumping into services, it helps to know the hierarchy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Organization&lt;/strong&gt; (company/domain; optional for personal projects)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Folders&lt;/strong&gt; (optional grouping)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Projects&lt;/strong&gt; (the main unit for billing, IAM, and resources)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resources&lt;/strong&gt; (VMs, buckets, databases, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most developers, a &lt;strong&gt;Project&lt;/strong&gt; is where everything begins.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: Use separate projects for &lt;code&gt;dev&lt;/code&gt;, &lt;code&gt;staging&lt;/code&gt;, and &lt;code&gt;prod&lt;/code&gt; if you can especially once billing and IAM start to matter.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Core GCP services developers should know&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1) Compute (where your code runs)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Run&lt;/strong&gt;: Run containers without managing servers. Great default for APIs, web apps, and workers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Engine&lt;/strong&gt;: PaaS-style deploys (less common in brand-new systems, but still used).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compute Engine&lt;/strong&gt;: Virtual machines (full control).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GKE (Google Kubernetes Engine)&lt;/strong&gt;: Managed Kubernetes for orchestration at scale.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rule of thumb:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you can containerize it → start with &lt;strong&gt;Cloud Run&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If you need orchestration across many services → consider &lt;strong&gt;GKE&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;If you need low-level control → use &lt;strong&gt;Compute Engine&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2) Storage (files and blobs)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Storage&lt;/strong&gt;: Object storage for uploads, artifacts, backups, media, static assets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Good use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User uploads (images/video)&lt;/li&gt;
&lt;li&gt;Build artifacts (zips, containers metadata)&lt;/li&gt;
&lt;li&gt;Data exports/imports&lt;/li&gt;
&lt;li&gt;Static website assets behind CDN&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3) Databases (store application data)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud SQL&lt;/strong&gt;: Managed PostgreSQL / MySQL / SQL Server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firestore&lt;/strong&gt;: NoSQL document database (great for event-driven/mobile/web apps).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spanner&lt;/strong&gt;: Globally distributed relational DB (powerful, enterprise-grade).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re building a typical web backend, &lt;strong&gt;Cloud SQL (Postgres)&lt;/strong&gt; is a great starting point.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;4) Messaging + async workloads&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pub/Sub&lt;/strong&gt;: Event streaming and messaging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Tasks&lt;/strong&gt;: Managed task queues (great for background jobs triggered by HTTP).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A common “serverless backbone” looks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloud Run (API) → Pub/Sub (events) → Cloud Run (worker)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;5) IAM (permissions)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;IAM controls &lt;strong&gt;who can do what&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prefer &lt;strong&gt;least privilege&lt;/strong&gt; over broad admin access&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;service accounts&lt;/strong&gt; for apps and automation&lt;/li&gt;
&lt;li&gt;Avoid giving everyone &lt;code&gt;Owner&lt;/code&gt; (it’s convenient and also risky)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;IAM feels annoying until it saves you from accidental production changes or surprise bills.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;A practical starter architecture (small, modern, scalable)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you want a “default” GCP stack for a new product:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Run&lt;/strong&gt; for your API (containerized)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud SQL (Postgres)&lt;/strong&gt; for relational data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Storage&lt;/strong&gt; for file uploads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secret Manager&lt;/strong&gt; for secrets (DB passwords, API keys)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Logging + Error Reporting&lt;/strong&gt; for observability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud Build&lt;/strong&gt; for CI/CD (optional, but very handy)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This setup is production-friendly without forcing you to operate servers.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Getting hands-on: a simple path to ship something&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Here’s a practical 30–60 minute plan:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create a GCP project&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable billing&lt;/strong&gt; (many services require it)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Install the Google Cloud SDK (&lt;code&gt;gcloud&lt;/code&gt;)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Deploy a small container to Cloud Run&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Add &lt;strong&gt;Cloud SQL&lt;/strong&gt; only after your service is deployed and reachable&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key is momentum: deploy something tiny first, then iterate.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Common mistakes (and how to avoid them)&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Using &lt;code&gt;Owner&lt;/code&gt; everywhere&lt;/strong&gt; → create scoped roles/service accounts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mixing regions randomly&lt;/strong&gt; → pick a region near your users and keep services aligned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No budgets/alerts&lt;/strong&gt; → set a budget alert on day one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Starting with Kubernetes too early&lt;/strong&gt; → Cloud Run often covers your needs for a long time.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;When GCP really shines&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;GCP is especially strong for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Analytics-heavy products&lt;/strong&gt; (BigQuery is a standout)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Event-driven systems&lt;/strong&gt; (Pub/Sub + Cloud Run)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes-based platforms&lt;/strong&gt; (GKE + ecosystem)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ML workflows&lt;/strong&gt; (Vertex AI + data tooling)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You don’t need to learn all of GCP to be productive. Pick a small core:&lt;br&gt;
&lt;strong&gt;Cloud Run + Cloud SQL + Cloud Storage + IAM + Logging&lt;/strong&gt;, and you can ship real services quickly.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>cloud</category>
      <category>google</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Getting Started with gRPC in Go (Golang): A Practical Guide</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Thu, 26 Mar 2026 21:25:26 +0000</pubDate>
      <link>https://dev.to/ghrabla/getting-started-with-grpc-in-go-golang-a-practical-guide-lo9</link>
      <guid>https://dev.to/ghrabla/getting-started-with-grpc-in-go-golang-a-practical-guide-lo9</guid>
      <description>&lt;p&gt;Modern applications are moving toward microservices and high-performance communication. If you're still using REST for everything, it might be time to explore a faster and more efficient alternative: gRPC.&lt;/p&gt;

&lt;p&gt;In this article, we’ll break down what gRPC is, why it’s powerful, and how to build your first service using Golang.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is gRPC?
&lt;/h2&gt;

&lt;p&gt;gRPC (Google Remote Procedure Call) is a high-performance RPC framework developed by Google. It allows services to communicate directly using function calls instead of traditional HTTP/JSON APIs.&lt;/p&gt;

&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /users/1
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;userService&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;UserRequest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why Use gRPC?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. High Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Uses HTTP/2&lt;/li&gt;
&lt;li&gt;Binary serialization with Protocol Buffers (Protobuf)&lt;/li&gt;
&lt;li&gt;Faster and more efficient than REST/JSON&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Strongly Typed APIs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Contracts are defined using &lt;code&gt;.proto&lt;/code&gt; files&lt;/li&gt;
&lt;li&gt;No ambiguity between services&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Streaming Support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Client streaming&lt;/li&gt;
&lt;li&gt;Server streaming&lt;/li&gt;
&lt;li&gt;Bidirectional streaming&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfect for real-time systems (chat apps, live data, etc.)&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Multi-language Support
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Works with Go, JavaScript, Python, Java, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Concepts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Protocol Buffers (Protobuf)
&lt;/h3&gt;

&lt;p&gt;This is where you define your API structure.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight protobuf"&gt;&lt;code&gt;&lt;span class="na"&gt;syntax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"proto3"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;service&lt;/span&gt; &lt;span class="n"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;rpc&lt;/span&gt; &lt;span class="n"&gt;GetUser&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;returns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UserResponse&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;UserRequest&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;message&lt;/span&gt; &lt;span class="nc"&gt;UserResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int32&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Code Generation
&lt;/h3&gt;

&lt;p&gt;From the &lt;code&gt;.proto&lt;/code&gt; file, you generate Go code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;protoc &lt;span class="nt"&gt;--go_out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--go-grpc_out&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; user.proto
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building a gRPC Server in Go
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Install Dependencies
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;go mod init grpc-demo
go get google.golang.org/grpc
go get google.golang.org/protobuf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Implement the Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"net"&lt;/span&gt;

    &lt;span class="n"&gt;pb&lt;/span&gt; &lt;span class="s"&gt;"grpc-demo/user"&lt;/span&gt;
    &lt;span class="s"&gt;"google.golang.org/grpc"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UnimplementedUserServiceServer&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserResponse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserResponse&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;   &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Kamal"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;lis&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;net&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"tcp"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;":50051"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;grpcServer&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewServer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterUserServiceServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;grpcServer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;{})&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"gRPC server running on port 50051..."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpcServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lis&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Building a gRPC Client in Go
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"context"&lt;/span&gt;
    &lt;span class="s"&gt;"log"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;

    &lt;span class="n"&gt;pb&lt;/span&gt; &lt;span class="s"&gt;"grpc-demo/user"&lt;/span&gt;
    &lt;span class="s"&gt;"google.golang.org/grpc"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dial&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"localhost:50051"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;grpc&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithInsecure&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Close&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewUserServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Background&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;defer&lt;/span&gt; &lt;span class="n"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;pb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserRequest&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"User:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  gRPC vs REST
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;gRPC&lt;/th&gt;
&lt;th&gt;REST&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Protocol&lt;/td&gt;
&lt;td&gt;HTTP/2&lt;/td&gt;
&lt;td&gt;HTTP/1.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Format&lt;/td&gt;
&lt;td&gt;Binary (Protobuf)&lt;/td&gt;
&lt;td&gt;JSON&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Faster&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Streaming&lt;/td&gt;
&lt;td&gt;Native support&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Browser Support&lt;/td&gt;
&lt;td&gt;Limited&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  When NOT to Use gRPC
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Public APIs consumed by browsers&lt;/li&gt;
&lt;li&gt;Simple CRUD services&lt;/li&gt;
&lt;li&gt;When debugging via browser is important&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;gRPC shines in internal microservices communication&lt;/p&gt;

&lt;h2&gt;
  
  
  Pro Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use gRPC Gateway if you need REST + gRPC&lt;/li&gt;
&lt;li&gt;Add interceptors for logging/authentication&lt;/li&gt;
&lt;li&gt;Combine with Docker for microservices&lt;/li&gt;
&lt;li&gt;Use TLS in production&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;gRPC with Go is a powerful combination for building fast, scalable, and modern backend systems. If you're targeting microservices or high-performance systems, it's a must-learn tool.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Understanding Goroutines and Channels in Go</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Tue, 10 Mar 2026 22:53:57 +0000</pubDate>
      <link>https://dev.to/ghrabla/understanding-goroutines-and-channels-in-go-5f25</link>
      <guid>https://dev.to/ghrabla/understanding-goroutines-and-channels-in-go-5f25</guid>
      <description>&lt;p&gt;Concurrency is one of the biggest reasons developers choose Go. While many languages require complex threading models or external libraries, Go provides a simple and powerful way to handle concurrent tasks using goroutines and channels.&lt;/p&gt;

&lt;p&gt;In this article, we’ll explore what goroutines and channels are, how they work, and how you can use them to build efficient concurrent programs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a Goroutine?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A goroutine is a lightweight thread managed by the Go runtime. Unlike operating system threads, goroutines are extremely cheap to create and can scale to thousands or even millions running at the same time.&lt;/p&gt;

&lt;p&gt;Creating a goroutine is simple: you just add the go keyword before a function call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello from goroutine"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;sayHello&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Main function finished"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens here?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The go keyword starts &lt;code&gt;sayHello()&lt;/code&gt; in a separate goroutine.&lt;/p&gt;

&lt;p&gt;The main function continues executing without waiting.&lt;/p&gt;

&lt;p&gt;We add time.Sleep so the program doesn’t exit before the goroutine runs.&lt;/p&gt;

&lt;p&gt;In real applications, we typically use synchronization mechanisms instead of sleep.&lt;/p&gt;

&lt;p&gt;Why Goroutines Are Powerful&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Traditional threads can be heavy and expensive. Goroutines solve this problem by being:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lightweight, very small memory footprint&lt;/li&gt;
&lt;li&gt;Fast to create&lt;/li&gt;
&lt;li&gt;Managed by the Go scheduler&lt;/li&gt;
&lt;li&gt;Perfect for I/O-heavy tasks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Examples of where goroutines shine:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Web servers handling many requests&lt;/li&gt;
&lt;li&gt;Background jobs&lt;/li&gt;
&lt;li&gt;API calls to multiple services&lt;/li&gt;
&lt;li&gt;Concurrent data processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Problem: Sharing Data Between Goroutines&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If multiple goroutines run at the same time, how do they communicate safely?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In many languages you would use:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Locks&lt;/li&gt;
&lt;li&gt;Mutexes&lt;/li&gt;
&lt;li&gt;Shared memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Go promotes a different philosophy:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Do not communicate by sharing memory; share memory by communicating.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is where channels come in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What Are Channels?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A channel is a typed conduit that allows goroutines to communicate and synchronize.&lt;/p&gt;

&lt;p&gt;You can send values into a channel and receive values from it.&lt;/p&gt;

&lt;p&gt;Creating a channel&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a channel that can transmit integers.&lt;/p&gt;

&lt;p&gt;Sending and Receiving Data&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;42&lt;/span&gt;
    &lt;span class="p"&gt;}()&lt;/span&gt;

    &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What’s happening?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We create a channel.&lt;/p&gt;

&lt;p&gt;A goroutine sends the value 42 into the channel.&lt;/p&gt;

&lt;p&gt;The main goroutine receives the value and prints it.&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;42
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Channels block by default, meaning:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sending waits until another goroutine receives&lt;/li&gt;
&lt;li&gt;Receiving waits until another goroutine sends&lt;/li&gt;
&lt;li&gt;This makes synchronization simple.&lt;/li&gt;
&lt;li&gt;Buffered Channels
Sometimes you don’t want the sender to block immediately. For that, Go provides buffered channels.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="s"&gt;"fmt"&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;

    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here the channel can store 2 values before blocking.&lt;/p&gt;

&lt;p&gt;Using Goroutines with Channels (Real Example)&lt;/p&gt;

&lt;p&gt;Let’s run multiple tasks concurrently and collect their results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"fmt"&lt;/span&gt;
    &lt;span class="s"&gt;"time"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Second&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Worker %d finished"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;chan&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;go&lt;/span&gt; &lt;span class="n"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;-&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output (order may vary):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Worker 2 finished
Worker 1 finished
Worker 3 finished
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Here we:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start 3 goroutines&lt;/li&gt;
&lt;li&gt;Each performs work&lt;/li&gt;
&lt;li&gt;Each sends a result back through the channel&lt;/li&gt;
&lt;li&gt;The main goroutine collects the results&lt;/li&gt;
&lt;li&gt;This pattern is very common in Go.&lt;/li&gt;
&lt;li&gt;Closing Channels&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes we want to signal that no more values will be sent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="nb"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;ch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The loop automatically stops when the channel is closed.&lt;/p&gt;

&lt;p&gt;When to Use Goroutines and Channels&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You should consider them when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running multiple independent tasks&lt;/li&gt;
&lt;li&gt;Making parallel API requests&lt;/li&gt;
&lt;li&gt;Processing jobs in background workers&lt;/li&gt;
&lt;li&gt;Building high-performance servers&lt;/li&gt;
&lt;li&gt;Streaming data between components&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Beginner Mistakes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Forgetting that goroutines are asynchronous&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your program might exit before goroutines finish.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Deadlocks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fatal error: all goroutines are asleep - deadlock!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens when goroutines are waiting on each other with no progress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Overusing goroutines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Just because goroutines are cheap doesn’t mean everything should be concurrent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Goroutines and channels are core features that make Go a powerful language for building scalable and concurrent systems.&lt;/p&gt;

&lt;p&gt;Instead of complex thread management, Go gives developers a clean and expressive model for concurrency.&lt;/p&gt;

&lt;p&gt;Once you master these two concepts, you'll unlock one of Go’s greatest strengths.&lt;/p&gt;

&lt;p&gt;If you're learning Go for backend development, mastering goroutines, channels, and concurrency patterns will significantly improve your ability to build fast and scalable services.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cleancode</category>
      <category>backend</category>
    </item>
    <item>
      <title>Why Go (Golang) Is Becoming a Favorite Language for Backend Developers</title>
      <dc:creator>Kamal Rhrabla</dc:creator>
      <pubDate>Thu, 05 Mar 2026 21:40:11 +0000</pubDate>
      <link>https://dev.to/ghrabla/why-go-golang-is-becoming-a-favorite-language-for-backend-developers-50j7</link>
      <guid>https://dev.to/ghrabla/why-go-golang-is-becoming-a-favorite-language-for-backend-developers-50j7</guid>
      <description>&lt;p&gt;In recent years, Go (commonly called Golang) has rapidly gained popularity among backend developers. Originally created at Google in 2009, Go was designed to solve real problems engineers faced when building scalable systems.&lt;/p&gt;

&lt;p&gt;Today, Go powers infrastructure and backend systems at companies like Uber, Dropbox, and Netflix.&lt;/p&gt;

&lt;p&gt;But what makes Go so attractive for modern backend development?&lt;/p&gt;

&lt;p&gt;Let’s explore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Simplicity and Readability&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the biggest strengths of Go is its minimalist design.&lt;/p&gt;

&lt;p&gt;Unlike many modern languages that continuously add complex features, Go intentionally keeps the language simple.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import "fmt"

func main() {
fmt.Println("Hello, Go!")
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are no unnecessary abstractions or complicated syntax rules.&lt;/p&gt;

&lt;p&gt;This simplicity allows developers to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn the language quickly&lt;/li&gt;
&lt;li&gt;Maintain large codebases more easily&lt;/li&gt;
&lt;li&gt;Reduce bugs caused by complex logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Built for Performance&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go is a compiled language, similar to C and C++.&lt;/p&gt;

&lt;p&gt;That means Go programs are compiled into native machine code, which makes them significantly faster than interpreted languages.&lt;/p&gt;

&lt;p&gt;Compared to languages like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;JavaScript&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go applications often provide much better performance, especially for CPU-intensive backend services.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Powerful Concurrency with Goroutines&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of Go’s most famous features is goroutines.&lt;/p&gt;

&lt;p&gt;A goroutine is a lightweight thread managed by the Go runtime.&lt;/p&gt;

&lt;p&gt;Creating thousands of concurrent tasks is incredibly easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;go processRequest()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Behind the scenes, Go manages scheduling and execution efficiently.&lt;/p&gt;

&lt;p&gt;This makes Go particularly powerful for building:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs&lt;/li&gt;
&lt;li&gt;Real-time systems&lt;/li&gt;
&lt;li&gt;Microservices&lt;/li&gt;
&lt;li&gt;Distributed systems&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Technologies like Docker and Kubernetes are actually written in Go because of these capabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Fast Compilation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Another underrated advantage of Go is extremely fast compilation.&lt;/p&gt;

&lt;p&gt;Large Go projects compile in seconds, which significantly improves developer productivity compared to languages with slower build processes.&lt;/p&gt;

&lt;p&gt;This fast feedback loop makes Go ideal for modern development environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Excellent Standard Library&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go ships with a very powerful standard library, which covers many common tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HTTP servers&lt;/li&gt;
&lt;li&gt;JSON processing&lt;/li&gt;
&lt;li&gt;File handling&lt;/li&gt;
&lt;li&gt;Cryptography&lt;/li&gt;
&lt;li&gt;Networking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, building a simple web server takes just a few lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package main

import (
"fmt"
"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello from Go server!")
}

func main() {
http.HandleFunc("/", handler)
http.ListenAndServe(":8080", nil)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this minimal code, you already have a working web server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6. Ideal for Microservices&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go has become a top choice for microservice architectures.&lt;/p&gt;

&lt;p&gt;Its advantages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;lightweight binaries&lt;/li&gt;
&lt;li&gt;fast startup times&lt;/li&gt;
&lt;li&gt;low memory usage&lt;/li&gt;
&lt;li&gt;strong concurrency support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These characteristics make Go perfect for cloud-native systems.&lt;/p&gt;

&lt;p&gt;This is why many modern cloud tools, including Terraform and Prometheus, are written in Go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When Should You Use Go?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go is particularly well suited for:&lt;/p&gt;

&lt;p&gt;✔ Backend APIs&lt;br&gt;&lt;br&gt;
✔ Cloud services&lt;br&gt;&lt;br&gt;
✔ DevOps tools&lt;br&gt;&lt;br&gt;
✔ Distributed systems&lt;br&gt;&lt;br&gt;
✔ High-performance network services  &lt;/p&gt;

&lt;p&gt;However, it may not be ideal for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;complex front-end applications&lt;/li&gt;
&lt;li&gt;heavy machine learning workloads&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Go proves that simplicity can scale.&lt;/p&gt;

&lt;p&gt;By focusing on performance, readability, and concurrency, Go has become one of the most powerful languages for building modern backend systems.&lt;/p&gt;

&lt;p&gt;Whether you're building APIs, infrastructure tools, or distributed platforms, Go offers a productive and efficient development experience.&lt;/p&gt;

&lt;p&gt;If you haven't tried Go yet, it might be the perfect language to add to your backend toolkit.&lt;/p&gt;

</description>
      <category>backend</category>
      <category>go</category>
      <category>programming</category>
      <category>softwaredevelopment</category>
    </item>
  </channel>
</rss>
