<?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: Itai Steinherz</title>
    <description>The latest articles on DEV Community by Itai Steinherz (@itaisteinherz).</description>
    <link>https://dev.to/itaisteinherz</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%2F212839%2Fbb4aa50c-2808-4b37-bf8b-b528239dded1.jpg</url>
      <title>DEV Community: Itai Steinherz</title>
      <link>https://dev.to/itaisteinherz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/itaisteinherz"/>
    <language>en</language>
    <item>
      <title>Uncommon Python Type Hints for Special Cases</title>
      <dc:creator>Itai Steinherz</dc:creator>
      <pubDate>Fri, 25 Aug 2023 11:37:52 +0000</pubDate>
      <link>https://dev.to/itaisteinherz/uncommon-python-type-hints-for-special-cases-3jpg</link>
      <guid>https://dev.to/itaisteinherz/uncommon-python-type-hints-for-special-cases-3jpg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Python is great at being a dynamically and strongly-typed programming language. However, once you get enough mileage working with large Python codebases, you’ll probably realize that dyanmic types can be confusing, cause bugs, and result in unexpected behavior. The folks maintaining Python realized this as well, and decided to implement a built-in way to add static type annotations in Python (see &lt;a href="https://www.python.org/dev/peps/pep-0484/"&gt;PEP 484&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;7 years have passed since then, and type hinting in Python has matured and evolved, with new features being implemented in every new Python version. In this post, I wanted to go over some of the more advanced and newly added features, with the hopes that you will find them useful and integrate them into your codebase.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A basic knowldge of type hinting in Python is assumed. If you need a refresher, I recommend &lt;a href="https://realpython.com/python-type-checking/"&gt;this guide from Real Python&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Parameter specification variables
&lt;/h2&gt;

&lt;p&gt;Let’s imagine you’d like to write a simple decorator, which will print a message every time a method is called:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from typing import Callable, TypeVar

R = TypeVar('R')

def log(func: Callable[..., R]) -&amp;gt; Callable[..., R]:
    def wrapper(*args, **kwargs):
        print('Method has been called!')
        return func(*args, **kwargs)

    return wrapper

@log
def add(a: int, b: int) -&amp;gt; int:
    return a + b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;In case you aren’t familiar with &lt;a href="https://docs.python.org/3/library/typing.html#typing.TypeVar"&gt;&lt;code&gt;TypeVar&lt;/code&gt;&lt;/a&gt;, a type variable lets you refer to the same type in multiple places without specifying the exact type.&lt;/p&gt;

&lt;p&gt;In the code snippet above, a type variable was used in the &lt;code&gt;log&lt;/code&gt; method type signature to annotate that the decorated method’s return type is the same as that of &lt;code&gt;func&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The following call to &lt;code&gt;add&lt;/code&gt; is invalid, and one would expect type checkers to report it as an error, however it will only fail at runtime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add(1, 'a') # Fails at runtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is because the the decorated &lt;code&gt;add&lt;/code&gt; has the typing &lt;code&gt;Callable[..., int]&lt;/code&gt; (with &lt;code&gt;...&lt;/code&gt; meaning arguments aren’t validated). &lt;a href="https://www.python.org/dev/peps/pep-0612/"&gt;PEP 612&lt;/a&gt; addresses this issue by introducing &lt;code&gt;ParamSpec&lt;/code&gt;. &lt;code&gt;ParamSpec&lt;/code&gt; variables are a new type of type variables, used for defining the dependencies between different callables (such as decorators and the decorated method).&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;ParamSpec&lt;/code&gt;, we can modify the example above to enforce the parameters types of the decorated method, while maintaining the decorator’s flexibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from typing import Callable, ParamSpec, TypeVar
P = ParamSpec('P')R = TypeVar('R')

def log(func: Callable[P, R]) -&amp;gt; Callable[P, R]:    def wrapper(*args: P.args, **kwargs: P.kwargs): print('Method has been called!')
        return func(*args, **kwargs)

    return wrapper

@log
def add(a: int, b: int) -&amp;gt; int:
    return a + b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following will now be reported as an error by the type checker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add(1, 'a') # Rejected by the type checker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This feature was shipped in Python 3.10.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  User-defined type guards
&lt;/h2&gt;

&lt;p&gt;Let’s assume you’re writing a utility method, validating that an object is of a desired type (used for &lt;a href="https://mypy.readthedocs.io/en/latest/type_narrowing.html"&gt;type narrrowing&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from typing import Union

RealNumber = Union[int, float]

def is_real_number(value: object) -&amp;gt; bool:
    return isinstance(value, int) or isinstance(value, float)

def print_value_type(value: object):
    if is_real_number(value):
        assert value == value.real # Error: invalid type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code is valid, however static type checkers will report an error. This is because a type checker doesn’t have enough information to verify that &lt;code&gt;value&lt;/code&gt; is a number. Using &lt;code&gt;TypeGuard&lt;/code&gt;, introduced in &lt;a href="https://www.python.org/dev/peps/pep-0647/"&gt;PEP 647&lt;/a&gt;, we can enable type narrowing by changing the return type hint of &lt;code&gt;is_real_numeber&lt;/code&gt; to &lt;code&gt;TypeGuard[RealNumber]&lt;/code&gt;. This will signal to type checkers that if the method returns &lt;code&gt;True&lt;/code&gt;, &lt;code&gt;value&lt;/code&gt; is of type &lt;code&gt;RealNumber&lt;/code&gt; (and if it returns &lt;code&gt;False&lt;/code&gt;, it isn’t). Now, type checkers won’t report any errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from typing import Union, TypeGuard
RealNumber = Union[int, float]

def is_real_number(value: object) -&amp;gt; TypeGuard[RealNumber]: return isinstance(value, int) or isinstance(value, float)

def print_value_type(value: object):
    if is_real_number(value):
        assert value == value.real
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This feature was shipped in Python 3.10.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Type hints for dictionaries with a fixed set of keys
&lt;/h2&gt;

&lt;p&gt;Let’s assume we’d like to describe a person using a dictionary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;person = {
    'name': 'Bob',
    'age': 32
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dictionary’s keys should be strings, but we don’t want to constrain the types its values. The type hint &lt;code&gt;Dict[str, Any]&lt;/code&gt; (or &lt;code&gt;dict[str, Any&lt;/code&gt;] in Python 3.9 and later - see &lt;a href="https://docs.python.org/3/library/stdtypes.html#types-genericalias"&gt;&lt;code&gt;GenericAlias&lt;/code&gt;&lt;/a&gt;). This is better than nothing, but doesn’t really enforce our requirements for what the person dictionary should look like.&lt;/p&gt;

&lt;p&gt;Using &lt;code&gt;TypedDict&lt;/code&gt;, introduced in &lt;a href="https://www.python.org/dev/peps/pep-0589/"&gt;PEP 589&lt;/a&gt;, we can now enforce the specific key name and value types in the dictionary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from typing import TypedDict

class Person(TypedDict):
    name: str
    age: int
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, a type checker will recognize and enforce the typing of the values (and keys) of &lt;code&gt;Person&lt;/code&gt; dictionaries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;person: Person = {
    'name': 'Bob',
    'age': 32
}
# Or even:
person = Person(name='Bob', age=32)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This feature was shipped in Python 3.8.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Self type hint
&lt;/h2&gt;

&lt;p&gt;Let’s assume we’re developing a program which keeps track of blockchain transactions. A transaction might be represented using this simple interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from abc import ABC
from typing import List

class Transaction(ABC):
    def __init__ (self, parents: List["Transaction"]):
        self.parents = parents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Bitcoin transactions, for example, we could implement &lt;code&gt;BitcoinTransaction&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class BitcoinTransaction(Transaction):
    def __init__ (self, sender: str, recipient: str, parents: List["Transaction"]):
        super(). __init__ (parents)
        self.sender = sender
        self.recipient = recipient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage of &lt;code&gt;BitcoinTransaction&lt;/code&gt; would look like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;parent = BitcoinTransaction(sender="Alice", recipient="Bob", parents=[])
transaction = BitcoinTransaction(sender="Bob", recipient="Alice", parents=[parent])
# Rejected by the type checker:
print(f"The parent sender is {transaction.parents[0].sender}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We received a type checking error because as far as the type checker is concerned, the type of &lt;code&gt;transaction.parents[0]&lt;/code&gt; is &lt;code&gt;Transaction&lt;/code&gt;, not &lt;code&gt;BitcoinTransaction&lt;/code&gt;. To fix this, we can use &lt;code&gt;Self&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from abc import ABC
from typing import List, Self

class Transaction(ABC):
    def __init__ (self, parents: List[Self]):
        self.parents = parents

class BitcoinTransaction(Transaction):
    def __init__ (self, sender: str, recipient: str, parents: List[Self]):
        super(). __init__ (parents)
        self.sender = sender
        self.recipient = recipient

parent = BitcoinTransaction(sender="Alice", recipient="Bob", parents=[])
transaction = BitcoinTransaction(sender="Bob", recipient="Alice", parents=[parent])
print(f"The parent sender is {transaction.parents[0].sender}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This feature was shipped in Python 3.11.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;The type hinting features we’ve explored should enable you to apply type checking to new categories of Python code, which previously couldn’t benefit from automated type checking. I hope this post will inspire you to write code that is more declarative, documented and reliable.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Making Meaningful Hacktoberfest Contributions</title>
      <dc:creator>Itai Steinherz</dc:creator>
      <pubDate>Fri, 09 Oct 2020 16:35:18 +0000</pubDate>
      <link>https://dev.to/itaisteinherz/making-meaningful-hacktoberfest-contributions-4g4n</link>
      <guid>https://dev.to/itaisteinherz/making-meaningful-hacktoberfest-contributions-4g4n</guid>
      <description>&lt;h2&gt;
  
  
  Motivation
&lt;/h2&gt;

&lt;p&gt;Following &lt;a href="https://blog.domenic.me/hacktoberfest/"&gt;core issues with Hacktoberfest that maintainers surfaced during the beginning of this year’s Hacktoberfest&lt;/a&gt;, DigitalOcean &lt;a href="https://hacktoberfest.digitalocean.com/hacktoberfest-update"&gt;made Hacktoberfest 2020 opt-in&lt;/a&gt;. However, this only improves one aspect of the real problem in my opinion.&lt;/p&gt;

&lt;p&gt;While maintainers are no longer forced to deal with swag-seeking random contributors, many people simply don’t know how to contribute to OSS in a way that’s meaningful and helpful. Because of this, I wanted to write a post on my own OSS contributions, and how you can make a positive impact on OSS, instead of a negative one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Hacktoberfest
&lt;/h2&gt;

&lt;p&gt;In case you’re unfamiliar with Hacktoberfest, &lt;a href="https://hacktoberfest.digitalocean.com"&gt;Hacktoberfest&lt;/a&gt; is an online event happening worldwide every October, where contributors are awarded some swag (T-shirts and stickers) for making contributions to open-source software (OSS).&lt;/p&gt;

&lt;h2&gt;
  
  
  My contributions to OSS
&lt;/h2&gt;

&lt;p&gt;I actually first started contributing to OSS through Hacktoberfest 2017, as I like free stuff and coding. My first contributions were small documentation improvements, bug fixes, and such. I liked interacting with nice developers from all over the world, and found OSS to be a nice way to explore cool projects.&lt;/p&gt;

&lt;p&gt;After my first Hacktoberfest, I wanted to make more substantial contributions to OSS projects, and so I looked for mature projects where I could step up, commit to working on more complex tasks, and work with the maintainers to get my work merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Hacktoberfest means for me
&lt;/h2&gt;

&lt;p&gt;To me, Hacktoberfest isn’t just about quick typo fixes or adding superlatives to READMEs (though I must admit I did do these types of changes a few times). Rather, it’s about familiarizing the global developer community with OSS and how it works, encouraging developers to contribute to OSS, as well as shining a light on these projects, and helping their maintainers with the burden of maintaining software for free.&lt;/p&gt;

&lt;h2&gt;
  
  
  How you can make a positive impact on OSS
&lt;/h2&gt;

&lt;p&gt;If you’re new to open-source, I’d recommend going over a first-timers guide such as &lt;a href="http://opensource.guide/how-to-contribute/"&gt;this one by GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Done with that, maybe watched a few videos on the topic, and know what you want to do? I’d pay special attention to the following points:&lt;/p&gt;

&lt;h3&gt;
  
  
  Be proactive
&lt;/h3&gt;

&lt;p&gt;OSS is already out there, waiting for you to become involved in it. The issues are there, but usually people won’t just tell you what to do. You’ll need to take initiative, look for the issues that deserve attention, and work on them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make an effort
&lt;/h3&gt;

&lt;p&gt;While the simplest way to contribute to OSS is to work on the issues anyone can observe just by taking a look around the project’s repo, you should aim to do more.&lt;/p&gt;

&lt;p&gt;If you can afford to invest a bit more time into OSS — look for the harder problems that people usually shy away from. These usually come in the form of issues that have been around for months and even years, core usability issues, missing documentation, and more. Working on them will leave a huge impact on the project, make you a meaningful part of it, and give you a sense of achievement and accomplishment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be as communicative as possible
&lt;/h3&gt;

&lt;p&gt;If you have an idea for a cool feature — that’s great! Just be sure to first open an issue for it, and discuss the details with the maintainers. Want to work on an existing issue? Also cool, but leave a comment on it first, saying you’d like to work on it. Many times I’ve encountered multiple people working on the same issue, and it’s just a shame, caused by a simple lack of communication.&lt;/p&gt;

&lt;p&gt;Note that I’m not saying you have to get prior permission for everything. For example, if you notice some logic in a library’s source code could be optimized, that’s awesome! You should totally open a PR with your suggested improvements. However, you shouldn’t do a major refactor without discussing it first with the project’s maintainers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be patient
&lt;/h3&gt;

&lt;p&gt;Contributing OSS is a marathon, not a sprint. Some PRs take many months and even years to get merged. It’s not that people don’t respect the time you invested into their project, but that they have other commitments as well. Doing OSS is hard, time-consuming, and not very rewarding in most cases. Keep in mind that the circumstances are different for everyone.&lt;/p&gt;

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

&lt;p&gt;I truly appreciate people putting their time into OSS, and think that everyone can be a meaningful part of the community. I hope you’ll be able to take a thing or two from this post, and wish you luck in your OSS endeavors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Thanks to &lt;a href="https://twitter.com/RabbiGreenberg"&gt;Ben Greenberg&lt;/a&gt; for reading drafts of this post and giving me valuable feedback.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>github</category>
      <category>hacktoberfest</category>
    </item>
    <item>
      <title>Getting Started with Cost Optimization on AWS</title>
      <dc:creator>Itai Steinherz</dc:creator>
      <pubDate>Tue, 10 Dec 2019 16:25:10 +0000</pubDate>
      <link>https://dev.to/itaisteinherz/getting-started-with-cost-optimization-on-aws-148p</link>
      <guid>https://dev.to/itaisteinherz/getting-started-with-cost-optimization-on-aws-148p</guid>
      <description>&lt;h2&gt;
  
  
  Prologue
&lt;/h2&gt;

&lt;p&gt;I’m a long-time user of AWS, and have been a cloud computing advocate for quite some time. However, it seems to me like cost optimization is a part of cloud computing which doesn’t get the attention it deserves. As I’m going to speak at &lt;a href="https://awscommunitydaytelaviv2019.splashthat.com"&gt;AWS Community Day Tel Aviv&lt;/a&gt; about it, I also wanted to write a post on the subject.&lt;/p&gt;

&lt;p&gt;This article will be an introduction to cost optimization (focused on AWS, as that’s the cloud provider I’m most familiar with), with the end goal being to give you some inspiration on how you can look differently at your own cloud bills and cut down on costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Five Pillars
&lt;/h2&gt;

&lt;p&gt;According to the &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/cost-optimization-laying-the-foundation/cost-optimization-pillars.html"&gt;AWS documentation&lt;/a&gt;, there are five general cost optimization pillars:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Right size&lt;/li&gt;
&lt;li&gt;Increase elasticity&lt;/li&gt;
&lt;li&gt;Leverage the right pricing model&lt;/li&gt;
&lt;li&gt;Optimize storage&lt;/li&gt;
&lt;li&gt;Measure, monitor, and improve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here, I chose to focus on the three pillars which I think are the most important to be familiar with.&lt;/p&gt;

&lt;h3&gt;
  
  
  Right size
&lt;/h3&gt;

&lt;p&gt;I’d recommend you to read Corey Quinn’s blogpost on the topic, &lt;a href="https://www.lastweekinaws.com/blog/right-sizing-your-instances-is-nonsense/"&gt;“Right Sizing Your Instances Is Nonsense”&lt;/a&gt;. Basically, your future needs when it comes to instance types are often unpredictable, and so you should choose a configuration that works for now and change it as necessary instead of opting for a specific instance type and commit to that. While this approach may sound a bit contradictory to AWS’ suggestion, it will enable you to be more flexible when working with the cloud, and react quickly to changes in your computing needs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Leverage the right pricing model
&lt;/h3&gt;

&lt;p&gt;Using &lt;a href="https://aws.amazon.com/ec2/spot"&gt;spot instances&lt;/a&gt; and &lt;a href="https://docs.aws.amazon.com/savingsplans/latest/userguide/what-is-savings-plans.html"&gt;Savings Plans&lt;/a&gt;, you can significantly cut down on EC2 costs for predictable as well as spontaneous compute needs.&lt;/p&gt;

&lt;p&gt;If you need as much flexibility as possible, the &lt;a href="https://aws.amazon.com/blogs/aws/new-savings-plans-for-aws-compute-services"&gt;Compute Savings Plans&lt;/a&gt; are the best option available, and they to apply Fargate in addition to EC2. See &lt;a href="https://aws.amazon.com/savingsplans/pricing"&gt;the pricing page&lt;/a&gt; for more info.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Compute Savings Plan&lt;/th&gt;
&lt;th&gt;EC2 Instance Savings Plan&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Term&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1 Year or 3 Year&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Platform/OS Flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Tenancy Flexibility (Shared vs Dedicated)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Regional availability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;All, except mainland China. Yes, that means GovCloud too!&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Overage charges&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Spend above your commit is charged at on-demand rates&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Region-specific&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Instance-specific&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purchase Options&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;No upfront, partial upfront, and all upfront&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discount&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Up to 66%&lt;/td&gt;
&lt;td&gt;Up to 72%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supports Fargate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://www.lastweekinaws.com/blog/aws-begins-sunsetting-ris-replaces-them-with-something-much-much-better"&gt;Corey Quinn’s post blogpost on Savings Plans&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another alternative for EC2 is using &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-reserved-instances.html"&gt;reserved&lt;/a&gt; instances, which are less flexible than the Savings Plans AWS offers, and aren’t much cheaper either (&lt;a href="https://www.gorillastack.com/news/aws-savings-plans-reserved-instances"&gt;this article&lt;/a&gt; contains a nice comparison of the two options).&lt;/p&gt;

&lt;h3&gt;
  
  
  Measure, monitor, and improve
&lt;/h3&gt;

&lt;p&gt;This means different things to different companies and organizations, but in general, you want to regularly go over your cloud bills and be aware of what you’re spending money on. In countless times, the bill will show that by simply turning off unused EC2 instances, you can save a large percentage of the bill.&lt;/p&gt;

&lt;p&gt;One useful monitoring tool is &lt;a href="https://aws.amazon.com/aws-cost-management/aws-budgets"&gt;AWS Budgets&lt;/a&gt;, which is built into the AWS Billing Dashboard and allows you to easily set your budget and be alerted when the current bill is exceeding your budget, or when it’s predicted to do so.&lt;/p&gt;

&lt;p&gt;Note that I’m mainly focused on compute costs in this post since those are usually the most significant expenses users face.&lt;/p&gt;




&lt;h2&gt;
  
  
  Updates from re:Invent 2019
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Compute Optimizer
&lt;/h3&gt;

&lt;p&gt;One of the most exciting releases from re:Invent 2019 (in my opinion) is the &lt;a href="https://aws.amazon.com/compute-optimizer"&gt;AWS Compute Optimizer&lt;/a&gt;. I’ve already talked about right-sizing instances and impractical it is, however Compute Optimizer changes a few things.&lt;br&gt;&lt;br&gt;
Compute Optimizer analyzes your compute workloads, and uses machine learning to process historical utilization metrics and offer recommendations which are predicted to reduce costs and improve performance.&lt;/p&gt;

&lt;p&gt;Corey Quinn already wrote a &lt;a href="https://www.lastweekinaws.com/blog/with-compute-optimizer-aws-finds-an-actual-use-for-ai-ml"&gt;whole blogpost on this&lt;/a&gt;, which I definitely recommend checking out. You can also read more about Compute Optimizer on the &lt;a href="https://aws.amazon.com/blogs/aws/aws-compute-optimizer-your-customized-resource-optimization-service"&gt;AWS News Blog&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fargate Spot
&lt;/h3&gt;

&lt;p&gt;Another important announcement is &lt;a href="https://aws.amazon.com/blogs/aws/aws-fargate-spot-now-generally-available"&gt;Fargate Spot&lt;/a&gt;, which basically means that you can now configure your Fargate cluster to use Spot instances when those are available, or use regular EC2 containers otherwise. Using Fargate Spot will enable users to save up to 70% (when compared to using a regular Fargate cluster). Combined with Compute Savings Plans, you can drastically cut down on Fargate costs, without compromising flexibility or elasticity.&lt;/p&gt;




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

&lt;p&gt;I personally think that cost optimization is less about cutting down on costs wherever possible, and more about using the right tool for the right job &lt;em&gt;(while remembering to shut down unused EC2 instances)&lt;/em&gt;. Plan for the future, leave room for as much flexibility as possible, and continuously adapt your cloud usage to your needs as you go.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Big thanks to &lt;a href="https://twitter.com/QuinnyPig"&gt;Corey Quinn&lt;/a&gt; for being a great resource on cloud cost optimization and inspiring me to dive into the topic.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>billing</category>
      <category>ec2</category>
      <category>fargate</category>
    </item>
  </channel>
</rss>
