Sage/Breville Barista Pro review

This is a super short review of this fairly popular espresso machine. I bought this last year, despite a lot of arguments from my wife. She even threatened to throw it out if I bought. I did. And now she demands latte/cappuccino every day!

My budget was pretty limited at that point, so other decent options (HX or even dual boiler machines) are out of reach. Barista Pro fits in my budget (and kitchen), and when Amazon had a very good discount on them, I pulled the trigger.

I was happy.

When it was new

Don’t laugh.

Pros:

Sage/Breville is feature oriented, and when you open the box, you have everything you need to get going: a milk jug, a 54mm portafilter with 4 different baskets (2 double shots (1 pressurized, 1 non pressurized), 2 single shot), and of course, a grinder built-in. If you are new, this is hugely important. Some sellers do not include the milk jug, or even tamper (looking at you, Lelit!), and it’s bad that you are excited to open your new fancy espresso machine and realize you can’t make a decent cappuccino due to lacking equipment. The UI is intuitive and easy to work with. Once you understand the basics, using the machine, UX wise, is simple and easy.

The flow is well defined, and smooth – you take the portafilter, put it in the holder and click – the grinder grinds coffee for you, in the fineness you chose and the time you pick. Then you take the tamper (attached to the machine using a magnet, a pretty smart design), tamp it, put it in the head, place your cup, and press a button. It is the convenience you are paying for.

Cons:

Once you open the box, you quickly realize this machine is not built to last. It’s a thin layer of stainless steel outside of plastic. Build quality is … fine, but don’t expect the same quality as Italy-made machine. It’s been reported that while Sage/Breville service is very good during warranty, but one you are out of warranty, you have to pay hefty fee for repairs, because they just break down. And repair usually means “replace”.

The machine is advertised as “3s start up time”. You press a button, and the machine is ready. Truth is, however, if you want to get better shots, you need to wait for at least 10m, and flush 1 or 2 cup first. With the empty portafilter inserted, press the double shots button, and let the hot water flows through it. It warms up the head, the portafilter, and make sure you get stabilized temperature in the boiler. Otherwise, your cups will be incredibly sour. Or some times, both sour of bitter!

The machine overall is quite noisy, both the grinder and the pump. it’s not a big deal until you have tried quieter machines. This is even more true when you have empty grinder, it sounds like it gonna break (it is fine to grind in a short amount of time, mind you)

Another downside is that this uses a 54mm portafilter. The portafilter itself is fine, well made and solid, but after a while, you will want to try out new things, like bottomless portafilter. But this is when you realize you are left with either options: 1. buy cheap no brand products from China or 2. absurdly expensive or 3. both. Should it come with a 58mm portafilter which is the “industry standard”, you will have more options from reputable brands, at reasonable prices.

The built-in grinder is merely adequate, it’s step conical burr grinder (some says it’s actual stepless, but you will need some “tricks” for that). You will be able to grind espresso with it, but not with the fineness adjustment needed to extract the best out of your coffee. Whenever you can, upgrade to a good espresso grinder would make a huge difference in your espresso. (Note: a good espresso grinder can easily cost $400 or more!). Also, cleaning it is not the easiest task – it’s doable, but requires additional tools (like a vacuum cleaner) to do it properly.

It’s messy to grind a double shot (18-20gr), because some coffee ground will be left on the portafilter holder, or on the drip tray. Yes you can use a dosing cup, or a funnel, but you will, once again, agonize the limited options of a 54mm portafilter.

So so

The included tamper is “serviceable”. It can be tucked in which is need, and it does it job. But I’d suggest to buy a nice, ergonomic tamper as soon as you can. It’ll make your experience much more enjoyable.

The steam wand is ok, but it is on the weak side, and it produces wetter steam than I would like. It is enough to froth the included milk jug, but if you want to use a bigger jug (so you can make 2 cappuccinos or 1 big latte in 1 go), it’ll not powerful enough.

The included milk jug is OK. Good ergonomic, but the wall is a bit too thin, so it gets hot very quickly. I had hard time holding it when it reaches 55*C. In comparison, my Motta one is only fairly warm even when the milk reaches 60*C (that is however not the perfect thing)

Summary

In the end, Barista Pro is a well rounded, full featured espresso machine. It’s a budget/entry one, capable of making good shots. You have everything you need to start going, but it also does not really excel in neither brewing, nor steaming. Once you horned your skill, upgrading to a better grinder, and a better machine 58mm portafilter will be a big step.

If you want to learn and can spend, of course.

How to spot Facebook Marketplace scams

With the pandemic going for more than 1 year (And still no end in sight), shipping has become a popular option for shopping on Facebook Marketplace. And that’s why scamming skyrocketed. To make the matters worse, Facebook provides little to no shopper protection. Your safety is yours to care about. So how to spot and stay away from scam, beside of other health safety procedures?

If a deal seems to be too good to be true, it is likely is. At this point of writing, PlayStation 5 is most frequently scammed. Anything which is less than 5500 SEK for the standard edition is suspicious. Scalpers who sell high demand product at much higher price than MSRP are another issue, but they are not mutually exclusive. A scammer can try to sell at higher price to make it more “authentic”, but most will try to lure more unsuspecting buyers by low prices.

Photos with low quality are another red flag. It is likely that the seller did not take the photos himself/herself but download from other listing, then upload again. Every time you upload photos to Facebook they reduce the quality a bit to reduce size. Do that a few times and you will notice the artifacts in the photo. If the photo is blurry or pixeled, take that as a warning.

Commerce profile too new: anything newer than 2019 should be questionable. Especially someone with very few friends. Check their profile if you think they are an actual person behind it.

Only offer shipping is another red flag. While some authentic sellers would prefer less contact, it is uncommon. Shipping means you have to Swish (a quick money transfer method in Sweden) before hand, and that means you have no guarantee once you did. If you Swish

Also, check if that seller is selling multiple items, and for each item, a new location is listed. That means the seller is trying to scam you into thinking he/she is far away, so shipping is required.

An example of a scammer

My not very proud experience is that I was scammed myself. I was browsing the MarketPlace, and saw a game (Ratchet & Clank PS5), for a very good price (250kr compared to normally 450-500kr or even more, because the game was new). Contacted the seller, he was responsive, and even offered 50:50 split on shipping cost. I checked his profile, everything seems to check out, so I took the bait. Swish-ed him 270kr. Waited for a few days. The game never came. Ask him if he shipped it, he said yes. Waited for a few days more and asked him what would he do. He never replied. Only a few days later, another buyer reported him for scamming. Same tactic, only this time he admitted to that buyer he never sent the game (a different one), and promised to refund the money. He never did.

Deep down, I wanted him to not be scammer. I even felt a bit sorry for him. What state would he be in, so he has to scam over that small amount of money. Only after a while, I realized he did it systematically. He scams that amount so most people will just accept it and move on. Even if they report him to the police (as the said buyer did), they will likely not do anything about it. He gets away with scamming multiple people like that.

Facebook protection for buyers is a joke. The most you can do is to report the listing as Scam, and they still do nothing about it. So better be cautious and protect yourself.

A super short review of XBox One X

I have been a PS4-fan (if I can call myself so) since the day I bought the original PS4 to play Dragon Age: Inquisition. At that point, PS4 is the clearly better choice than XBox One: smaller without a separate power adapter, 50% more powerful (1.84TFLOPS vs 1.23 TFLOPS), simpler policies to share/resell game, etc etc.

I even liked XBox One X when it was announced, it checks almost all the boxes, except for, well, games and price, so I gave it a pass, especially when I got a PS4 Pro from a colleague at a very good price. This genre, PS4 has won for many reasons, one of that is it has a excellent line of exclusive.

Why not all three of them? Why choose side?

And I remain faithful until the day Elgiganten – a big electronic retailer in Sweden sells Xbox One X with Fallout 76 bundle at an unbeatable price (cheaper than Xbox One X selling alone, so the game actually reduces the price of the bundle!). I talked to myself – why not, if I don’t like it I can just return (it’s turned out that the game is digital, so I won’t be able to return. But I like it in the end so I decided to keep it. I find myself playing Apex Legends every night now, and I’m happy with it)

I won’t play Fallout 76, but this is cheaper than the Xbox One X alone, thanks to it.

The good

A marvel of engineering. It’s significantly more powerful than my PS4 Pro, yet it is just the same size and is even more quiet.

Incredible value if you think about Game Pass. Bunch of good games at a very low price, especially when you use the promotions that happen all the time. I spent about 30 SEK (less than 4 USD) for 3 months of that.

The controller battery lasts me weeks, and it takes only 1 minute or so to replace the battery.

A new generation of gamers!

Games that are optimized for X run exceptionally well. Forza Horizon 4, Red Dead Redemption 2, just to name a few.

Xbox and Xbox 360 games backward compatibility.

UHD Blu-ray player.

The bad

The UI is a mess. I complained about how HBO UI is a mess . But I think XBox One UI is on par in term of terrible.

The ugly

The Blu-ray player that refuses to play my UHD bluray, 9 out of 10 times.

I will have to re-buy many games to get the advantage of native 4K.

Fixing ASP.NET Membership performance – part 1

Even though it is not the best identity management system in the .NET world, ASP.NET Membership provider is still fairly widely used, especially for systems that have been running for quite long time with a significant amount of users: migrating to a better system like AspNetIdentity does not comes cheap. However, built from early days of ASP.NET mean Membership provider has numerous significant limitations: beside the “architecture” problems, it also has limited performance. Depends on who you ask, the ultimate “maximum” number of customers that ASP.NET membership provider can handle ranges from 30.000 to 750.000. That does not sound great. Today if you start a new project, you should be probably better off with AspNetIdentity or some other solutions, but if your website is using ASP.NET membership provider and there is currently no plan to migrate, then read on.

The one I will be used for this blog post has around 950.000 registered users, and the site is doing great – but that was achieved by some very fine grained performance tuning, and a very high end Azure subscription.

A performance overview 

I have been using ASP.NET membership provider for years, but I have never looked into it from performance aspects. (Even though I have done some very nasty digging to their table structure). And now I have the chance, I realize how bad it is.

It’s a fairly common seen in the aspnet_* tables that the indexes have ApplicationId as the first column. It does not take a database master to know it is a very ineffective way to create an index – in most of the cases, you only have on ApplicationId in your website, making those indexes useless when you want to, for example, query by UserId. This is a rookie mistake – a newbie tends to make order of columns in the index as same as they appear in the table, thinking, that that SQL Server will just do magic to exchange the order for the best performance. It’s not how SQL Server – or in general – RDBMS systems work.

It is OK to be a newbie or to misunderstand some concepts. I had the very same misconception once, and learned my lessons. However, it should not be OK for a framework to make that mistake, and never correct it.

That is the beginning of much bigger problems. Because of the ineffective order of columns, the builtin indexes are as almost useless. That makes the queries, which should be very fast, become unnecessarily slow, wasting resources and increasing your site average response time. This is of course bad news. But good news is it’s in database level, so we can change it for the better. It if were in the application level then our chance of doing that is close to none.

Missing indexes

If you use Membership.GetUserNameByEmail on your website a lot, you might notice that it is … slow. It leads to this query:

        SELECT  u.UserName
        FROM    dbo.aspnet_Applications a, dbo.aspnet_Users u, dbo.aspnet_Membership m
        WHERE   LOWER(@ApplicationName) = a.LoweredApplicationName AND
                u.ApplicationId = a.ApplicationId    AND
                u.UserId = m.UserId AND
                LOWER(@Email) = m.LoweredEmail

Let’s just ignore the style for now (INNER JOIN would be a much more popular choice), and look into the what is actually done here. So it joins 3 tables by their keys. The join with aspnet_Applications would be fairly simple, because you usually have just one application. The join between aspnet_Users and aspnet_Membership is also simple, because both of them have index on UserId – clustered on aspnet_Users and non-clustered on aspnet_Membership

The last one is actually problematic. The clustered index on aspnet_Membership actually looks like this

CREATE CLUSTERED INDEX [aspnet_Membership_index]
    ON [dbo].[aspnet_Membership]([ApplicationId] ASC, [LoweredEmail] ASC);

Uh oh. Even if this contains LoweredEmail, it’s the worst possible kind of index. By using the least distinctive column in the first, it defeats the purpose of the index completely. Every request to get user name by email address will need to perform a full table scan (oops!)

This is a the last thing you want to see in a execution plan, especially with a fairly big table. 

It should have been just

CREATE CLUSTERED INDEX [aspnet_Membership_index]
    ON [dbo].[aspnet_Membership]([LoweredEmail] ASC);

which helps SQL Server to use the optimal execution plan

If you look into Azure SQL Database recommendation, it suggest you to create a non clustered index on LoweredEmail. That is not technically incorrect, and it still helps. However, keep in mind that each non clustered index will have to “duplicate” the clustered index, for the purpose of identify the rows, so keeping the useless clustered index actually increases wastes and slows down performance (even just a little, because you have to perform more reads to get the same data). However, if your database is currently performing badly, adding a non clustered index is a much quicker and safer option. The change to clustered index should be done with caution at low traffic time.

Tested the stored procedure on database above, without any additional index

Table 'aspnet_Membership'. Scan count 9, logical reads 20101, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'aspnet_Applications'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'aspnet_Users'. Scan count 0, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 237 ms,  elapsed time = 182 ms.

With new non clustered index


(1 row affected)
Table 'aspnet_Applications'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'aspnet_Users'. Scan count 0, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'aspnet_Membership'. Scan count 1, logical reads 9, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 15 ms,  elapsed time = 89 ms.

With new clustered index:

(1 row affected)
Table 'aspnet_Applications'. Scan count 0, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'aspnet_Users'. Scan count 0, logical reads 7, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'aspnet_Membership'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.

(1 row affected)

 SQL Server Execution Times:
   CPU time = 0 ms,  elapsed time = 89 ms.

Don’t we have a clear winner?

Why I left Metacritic, for good.

I’m a mediocre gamer, by any measures, but that does not defy the fact that I love playing games. Great games, only. With my very limited time and budget, I must to be very selective about the games I play. For a very long time, Metacritic is my to-go website to check if I should play a game – and I set my rules rather high: anything less than 80 is a big no-no. Less than 85 is a no, unless it’s a sequel of a game I loved so much (so I can see how the story turned out to be). More than 85 is “I’ll think about it” (when it comes with a very tempting discount, I might make up my mind). A game of at least 90 Metacritic score will be in my short list (but not necessary in my playing list). A game of at least 95 Metacritic means “must try” for me. I might not love it, but a game with such reviews must have something I like about.

However, overtime, I did realize what MetaCritic is really meant to be, and why reviews can be full of sh*t.

Game reviews, as almost other content in the Internet, include the post you are reading, are opinions. It’s opinion, just like you and me, but the only thing that makes critics stand out is professionalism.

But that’s not something I’ve seen in many reviews which are listed on Metacritic.

You can either love, or hate a game. You can talk about it, openly, it’s your rights! But if you want to help your readers decide if they should  buy or play the game, based on your judgement, you have to be fair. Your opinions have to be as objective as possible. Of course, there is no such thing as “true objective” in reviews, but yours should have a reasonable amount in them.

Unfortunately, in this area of internet, clicks and views are everything. More views mean more ads impressions, ads clicks, and that mean more money.

The best known trick for clicks, is of course, controversial opinion.

Metacritic has a fairly easy review policy. The only measurable criteria is you have to have at least 30 reviews in your website, and you have to review fairly regularly. All other criteria about ethical or professionalism are indeed subjective. And that are being heavily abused.

Less known websites have been using that tactic to draw attention to their website. By giving a highly anticipated game an unreasonable low score, they create the controversy. People will urge to visit their websites to comment on the absurd review, or even sharing the reviews so their friends can attack them.

Who is benefiting? Do you have to guess?

Let’s talk about the infamous Washington Post’s Uncharted 4: A thief end review. Of 113 reviews averaging 93/100, they gave them 2/5 (equivalent to 40/100).

Or the slightly less infamous, USGamer’s Horizon: Zero Dawn review: 5/10 for a game which is otherwise rated 89/100.

Can you imagine it?

And Washington Post is not the only one. GameCritics, another less known site, has jumped in a gave the game a 50/100.

You can be harsh – that’s what famous magazine like Edge is known for – but you also need to be fair. You can criticize a game as much as you like, as long as the criticism is objective – why don’t you like it, and what it can have done better. When you bash a game because it’s not your taste, you become biased. The said review from WP was even disagreed by their staff

I’ve never disagreed more with a piece of content on our website as I have with this. haha  

The worst thing is this kind of shaggy tactic is not per review. Some sites are known to use it systematically, hoping to attract more clicks to the website:

GameCritics is just slightly better:

You see the pattern here? Well, you can expect those websites will, more often than not, give the lowest scores to a highly anticipated game, so their reviews become more visible and attract more clicks. People would go their and bash their review, like they themselves did with the game. In the end, who’s getting the benefits here?

Metacritic has changed the way we look at reviews. Before Metacritic, it’s more difficult to get a fairly balance, objective views of the game. But the good deed of Metacritic is being abused and if they don’t do anything to fight that, they will soon obsolete themselves.

Useful T-SQL snippets for development and troubleshooting

This post is more of a note-to-self. These are the useful T-SQL statements which can be incredibly useful in development and troubleshooting

SET STATISTICS IO ON

Turn on the IO statistics for statements run after that until set to OFF explicitly. We then switch to Messages tab to see how many IO operations were done on each table.

SET STATISTICS TIME ON

Find out about the statements were executed: which statements, its texts, how many reads (logical), how many time was spent on CPU and how many time was spent total

Continue reading “Useful T-SQL snippets for development and troubleshooting”

Choose your battles

This is the third part of the series: How to survive and thrive – a series for new developers to become better at their jobs. You can read the first two parts here and here.

In military, there is a term of “uphill battle”. That when you have to fight your way up a hill, when you enemy controls the top. It’s a very difficult fight and your chance of success is low. Any experienced military leader knows uphill battles are something you should avoid until there are no other options.

That also applies with any jobs. Including programming.

The truth is, you shouldn’t fight the battles you can’t win.
Continue reading “Choose your battles”

Mass update catalog entries

This is something you don’t do daily, but you will probably need one day, so it might come in handy.

Recently we got a question on how to update the code of all entries in the catalog. This is interesting, because even thought you don’t update the codes that often (if at all, as the code is the identity to identify the entries with external system, such as ERPs or PIMs), it raises a question on how to do mass update on catalog entries.

    • Update the code directly via database query. It is supposedly the fastest to do such thing. If you have been following my posts closely, you must be familiar with my note regarding how Episerver does not disclose the database schema. I list it here because it’s an option, but not the good one. It easily goes wrong (and cause catastrophes), you have to deal with versions and cache, and those can be hairy to get right. Direct data manipulation should be only used as the last resort when no other option is available.

Continue reading “Mass update catalog entries”

The art of paging

No this is not really “art” – I’m just trying to have a more clickbait title. It’s more about understanding what you have at your disposal and use them for your benefits – in this case – how new SQL statement can drastically improve your performance.

In this blogpost we will look into paging feature of SQL Server. in Commerce we usually work with large set of data – millions of rows are fairly common, and it’s natural to load data by page. There is no point loading thousands, or even millions of rows in one go. First it’s not practical to display all of them. Second you’ll likely end up with an timeout exception and/or an out of memory exception. Even if you are lucky enough to get through, it’s still able to take your SQL Server instance to a knee, and transferring that much data over network will be another bottleneck for your system. So my friends, the best practice for loading data is to do it by batches, and to not load everything at once.

Continue reading “The art of paging”