Firefox 30.0 - <AUTHOR> http://www.mozilla.org/en-US/firefox/30.0/releasenotes/ <comment><USER2> > Ignore autocomplete="off" when offering to save passwords via the password > manager

Love this change. There's some good conversations in Bugzilla about it. [0]

[0]: [https://bugzilla.mozilla.org/show_bug.cgi?id=956906](https://bugzilla.mozilla.org/show_bug.cgi?id=956906)

<comment><USER3> This is going to cause trouble with several websites that use "password" inputs for other sensitive data like credit card numbers and SSNs. The discussion mentions that this is a misuse of the password input, but it's a very common misuse of it.

The discussion stresses that Firefox is the third major browser to implement this feature, but what I don't think they understand is that their username/password detection algorithm is the weakest of the three browsers.

If I create a form that contains a dozen fields, one of which is labeled "Owner's Email" (type=text) and another that is labeled "Owner's SSN" (type=password) with several fields in between, Firefox thinks this is a login and prompts the user to save this information. Chrome and IE are smart enough to recognize that just because an email address and password field were somewhere on the same form, that this isn't login information.

We've addressed this issue in the past by turning autocomplete=off for the SSN field, but now we'll have to re-implement input type=password using input type=text with some javascript. Otherwise, our users are going to accidentally click "Yes" at some point when prompted to save their password and have the form auto-filled for each subsequent entry.

<comment><USER4> What about them wanting to save the field? Don't tell your users what to save and what not to. It's REALLY annoying!

<comment><USER3> Because the value will be different every time the user uses the application. These are basically data entry people keying in paper forms all day.

<comment><USER4> Why not use type="text" then?

</comment></comment></comment></comment></comment><comment><USER5> I love the change to prohibit non-whitelisted plugins. Together with the changes to Chrome to move away from NPAPI, hopefully we can kill off the majority of plugins across all browsers.

If we can get it down to just Flash and nothing else, hopefully a few years from now Mozilla's HTML5 implementation of Flash will take off (similar to PDF.js), which pushes Flash inside the browser sandbox, and ensures that it has no more privileges or capabilities than normal in-browser content.

<comment><USER6> Even Flash I keep it on click to play. Doesn't bother me much, except when I want to view YouTube videos and such and I don't watch videos all day.

<comment><USER7> ClickToPlugin on Safari is reeeeally good at finding the html5 alternative for Flash videos. It's actually the only thing that's keeping me on Safari, if only someone could port it to firefox…

<comment><USER8> Greasemonkey + ViewTube ([http://isebaro.com/viewtube/?ln=en](http://isebaro.com/viewtube/?ln=en)) + ViewTube Plus ([https://openuserjs.org/scripts/hamsterbacke/ViewTubePlus](https://openuserjs.org/scripts/hamsterbacke/ViewTubePlus)).

<comment><USER7> I tried those already, but It just won't work as consistently and as easily.

</comment></comment></comment></comment></comment><comment><USER9> I'm still eagerly waiting for per tab volume control [0], a per tab activity monitor/profiler [1], the possibility to suspend tabs with practically no memory usage [2] and more options for searching the browsing history [3]. Besides that I find it counterintuitive that a revisit of an URL removes the entry of the previous visit. The result is an incomplete history. I wished they would change that.

[0]: [https://bugzilla.mozilla.org/show_bug.cgi?id=728046](https://bugzilla.mozilla.org/show_bug.cgi?id=728046)

[1]: [https://bugzilla.mozilla.org/show_bug.cgi?id=400120](https://bugzilla.mozilla.org/show_bug.cgi?id=400120)

[2]: [https://bugzilla.mozilla.org/show_bug.cgi?id=675539](https://bugzilla.mozilla.org/show_bug.cgi?id=675539)

There are add-ons for suspending tabs but in my experience not very robust ones

[3]: Full text search and search operators for time intervals would be great.

<comment><USER10> Per tab volume control is impossible with NPAPI. Unless Adobe does something, Shumway has to be the solution for that.

<comment><USER11> Technically, they could set LD_LIBRARY_PATH (or equivalent in Windows) and provide a sound API wrapper library that could control the volume. That sounds overkill, though.

<comment><USER12> Isn't that basically what pulse audio does (on an application level, not tab level)?

</comment></comment></comment></comment><comment><USER13> Wow, I'm surprisingly stoked about this change:

      Use of line-height allowed for <input type="reset|button|submit">

Firefox was the only browser who didn't allow you do that!

<comment><USER14> Yup. The same goes for dropdown list '<select>' elements. No mention of that in this release though.

<comment><USER15> That's [https://bugzilla.mozilla.org/show_bug.cgi?id=454625](https://bugzilla.mozilla.org/show_bug.cgi?id=454625) and the problem is that other browsers only sometimes allow changing line- height on them and some sites are depending on that (non-documented, not standardized) behavior...

</comment></comment></comment><comment><USER16> This _Firefox is already running_ bug is really annoying. I love Firefox but it's some poor UX when i manually have to shutdown the process.

<comment><AUTHOR> I wonder why this only seems to be a problem for some people... It has happened to me only once in the 1000's of times I have shutdown Firefox since version 29.

<comment><USER16> But still once in 1000 times is worse than none, isn't it? And it has happened more than once for me...

<comment><AUTHOR> Well, I have needed to manually shutdown the Firefox process prior to Firefox 29 (every once in a great while) so having to do it once so far with the new version is not significant.

I am not saying it's not a real issue but why it's more a problem for some then others...

<comment><AUTHOR> OK, now after my previous comments I have had to manually shutdown Firefox twice today. It's a problem...

</comment></comment></comment></comment></comment><comment><USER17> Would it really be so hard to support a calendar?

[http://robertnyman.com/html5/forms/input- types.html](http://robertnyman.com/html5/forms/input-types.html)

<comment><USER18> I feel like a calendar input should probably be a custom element. There are too many possible variations.

<comment><USER19> I upvoted and tend to agree with you but I wonder if 90% of uses couldn't be addressed through a relatively small (hah!) amount of CSS customizability of the element.

<comment><USER20> Probably, if you only want to support the en-us locale. Of course, in the real world that's not 90% of use cases...

</comment></comment></comment></comment><comment><USER21> Am I only one who thinks it is crazy that all the web browsers look the same now? [http://jmoses.co/2014/06/10/which-browser-is- which.html](http://jmoses.co/2014/06/10/which-browser-is-which.html)

<comment><USER22> It's like asking "why are all these blank sheets of paper so similar?" Browsers are getting more minimal because browser chrome just gets in the way of the content.

Anyway they're not that similar. Firefox has a search bar, refresh button on the right, and no greyed-out "forward" button. Opera has the speed dial buttons. And Chrome would be the most "minimal" if it weren't for the extension icons over on the right.

</comment></comment><comment><USER23> Best browser just keeps getting better!

Hopefully this gets some more people over from the closed-source Google Chrome.

</comment><comment><USER24> Firefox is getting more awesome with each update, but admittedly I'm kind of liking Chrome's implement first, standardize later approach to new features, which is why you can get a directoryReader in Chrome and drag and drop support for uploading entire directories. I wish Firefox had that, but it's not a standard so they're not implementing it.

<comment><USER25> Both Chrome and Firefox have the same approach of implementing first, standardizing later. For example, Firefox has had large swaths of ES6 implemented since 2006 or so.

Rather, it's not so much that they refuse to implement features until they're standardized, it's that each browser maker refuses to implement the features dreamed up by the _other_ browser makers until they're standardized.

<comment><USER24> > Both Chrome and Firefox have the same approach of implementing first, > standardizing later

>Rather, it's not so much that they refuse to implement features until they're standardized, it's that each browser maker refuses to implement the features dreamed up by the other browser makers until they're standardized.

I guess that's what happened with this. A Mozilla engineer explicitly argued against implementing something because it's not a standard in this issue: [https://bugzilla.mozilla.org/show_bug.cgi?id=782233](https://bugzilla.mozilla.org/show_bug.cgi?id=782233)

</comment></comment></comment><comment><USER26> Based on the notes in #812695[1] the longstanding text-corruption bug that's appeared in past releases should be fixed thanks to a change in how the layout's handled.

[1]: [https://bugzilla.mozilla.org/show_bug.cgi?id=812695#c414](https://bugzilla.mozilla.org/show_bug.cgi?id=812695#c414)

</comment><comment><USER27> CSS scale transition performance is still janky on OS X. Are they ever going to fix that?

<comment><USER28> Please post a link to a site where you see that happening.

<comment><USER27> [https://bugzilla.mozilla.org/show_bug.cgi?id=847653](https://bugzilla.mozilla.org/show_bug.cgi?id=847653)

It should hiccup on Firefox for Mac but virtually no other browser: [http://jsfiddle.net/K7Ukb/8/](http://jsfiddle.net/K7Ukb/8/)

<comment><USER29> FWIW: On a 2011 MBP 17", it was silky smooth in Chrome, and very slightly slightly less smooth on FF and Safari.

<comment><USER30> Chrome is fast and smooth, IE doesn't do anything.

but this is Win7.

</comment></comment></comment></comment></comment><comment><USER31> I love Firefox, but since I upgraded from 28 to 29, it has been crashing for me on Win 7 on a daily basis. Looking in about:crashes I have close to 30 crashes reported. The moment I upgraded to 30, it crashed. _sigh_

<comment><USER32> do you happen to have the extension HTTPS Everywhere installed? I had that problem and disabled the SSL Observatory and it started working fine again.

Hopefully it will be fixed soon (if not already)

<comment><USER31> Yes, I have HTTPS Everywhere installed. I will disable SSL Observatory and see if that helps. Thanks for the tip.

</comment></comment></comment><comment><USER33> Does it strike anyone else as odd that they don't highlight security updates as Chrome does? Example, [http://googlechromereleases.blogspot.com/2014/05/stable- chan...](http://googlechromereleases.blogspot.com/2014/05/stable-channel- update_20.html) Maybe it's psychological, but I like the reassurance security is a focus for Chrome.

<comment><USER28> You can see the security advisories here:

[https://www.mozilla.org/security/announce/](https://www.mozilla.org/security/announce/)

<comment><USER34> [http://www.mozilla.org/security/known- vulnerabilities/firefo...](http://www.mozilla.org/security/known- vulnerabilities/firefox.html)

</comment></comment></comment><comment><USER35> Still no keyring/OS password storage support? I'm all for storing all passwords in the password manager (including those with autocomplete="off") but anything that can read signons.sqlite has access to all passwords in cleartext (no average user uses the master password)

<comment><USER36> Are you sure? I just did a .dump on my signons.sqlite. The login and passwords are not stored in cleartext.

ubuntu 13.10 firefox 27.0.1

</comment></comment><comment><USER37> There seems to be a bug on the dev-tools in the Network tabs, I cannot see the labels that are normally at the bottom ("All | HTML | CSS ... "). It seems that the container that's wrapping them doesn't have enough height to show the text. This is on OS X 10.9.3. Anyone else having this issue?

</comment><comment><USER38> Why limit yourself to just firefox 30.0 I'm using their Mozilla Nightly currently at 33.0a1 (2014-06-10)

<comment><USER28> Awesome! We can always use more people using the Nightly or Beta channels. Just be aware that you are not getting production quality code.

In general Nightly has been very stable for me, but sometimes things sneak in that are annoying or simply broken. If you can live with that, then welcome to Nightly! :-)

<comment><USER39> The only time I ever have problems with nightly is the first release of a new version. I wish I could set a config entry to wait for the second release of a new version.

<comment><USER40> The Aurora release channel might be what you're looking for - it's between the beta and nightly channels. I find it to be exciting and fairly stable.

[http://www.mozilla.org/en- US/firefox/channel/#aurora](http://www.mozilla.org/en- US/firefox/channel/#aurora)

</comment></comment></comment></comment><comment><USER41> Why in the inspector does it convert the markup to xml?

So it adds < / input > etc

<comment><USER42> It's a sort-of serialized representation of the DOM.

<comment><USER41> I thought </input> was the proper way to write HTML.

<comment><USER42> It's either <input ...> (SGML flavor) or <input .../> (XML flavor).

</comment></comment></comment></comment><comment><USER43> Anyone know if array comprehensions are also supported in chrome?

<comment><USER44>
        var xs = 1, 2, 3
        [for (x of xs) x * 2]
        SyntaxError: Unexpected token for

Chrome Version 35.0.1916.114

</comment></comment><comment><USER45> Unfortunately no gstreamer 1.0 in official Mozilla builds yet.

<comment><USER46> It's item #3 in the release notes. [http://www.mozilla.org/en- US/firefox/30.0/releasenotes/](http://www.mozilla.org/en- US/firefox/30.0/releasenotes/)

<comment><USER45> It's available as an option at build time (build switch). But it's not used in the official Mozilla builds which are still built against gstreamer 0.10.

</comment></comment></comment><comment><USER47> There is a telephone in Firefox Nightly.

</comment><comment><USER48> It was only yesterday when Firefox was 3 and look at it now. Isn't it about time we start telling it to get married and have children or?

</comment><comment><USER49> I've uninstalled Firefox since Mozilla ousted Brandon Eich

<comment><USER50> Sorry to here you hate homosexuals.

</comment></comment><comment><USER51> While it's quite off topic, what's with FF version numbers? I mean just a few years back it was FF 3, 4, 5, and while I am not using it daily, I don't think it's a major change every time.

I guess my kids are going to use Firefox 142...

<comment><USER22> As scott_karana mentioned, Firefox has been doing "rapid release" since 2011. [https://wiki.mozilla.org/RapidRelease](https://wiki.mozilla.org/RapidRelease) There are 3 channels: Aurora (alpha), Beta, and Release. Every 6 weeks, stable features are pushed into the next channel. So there is a new release every 6 weeks, and if you want to live in the future, you can use the Beta or Aurora channel. [https://www.mozilla.org/en- US/firefox/channel/](https://www.mozilla.org/en-US/firefox/channel/)

Edit: do you really want your grandkids to be stuck with version 5? :)

<comment><USER52> And don't forget about nightly: [http://nightly.mozilla.org/](http://nightly.mozilla.org/)

<comment><USER53> And the news-feed: [http://firefoxnightly.tumblr.com/](http://firefoxnightly.tumblr.com/)

</comment></comment></comment></comment><comment><USER54> Very nice, but those designer tabs from FF29 still make my eyes bleed every time I see them, so I'm stuck on FF28. I wonder how many people are in the same situation :-|

<comment><USER55> Only someone who is completely unconcerned with the security of their computer since 29.0 and later fix critical bugs allowing for remote code execution. Seriously, I'd recommend doing one of the following:

1\. Upgrade and use one of the theme and extension combinations to get a look you want.

2\. Upgrade and just get used to the new look since it's similar to Chrome and others.

3\. Downgrade to Firefox ESR 24.5.0 which IS fully secure.

<comment><USER56> Blah blah blah, security! Oh, boo-hoo security!

If security is such a hot button worry wart issue, then it shouldn't be permissible for Mozilla developers to bind minor UI tweaks to security fixes. Firefox user interface changes should not be tightly coupled with essential security updates, since they introduce the hazard of many users refusing to comply with good security practices, simply because some asshole design wonk decided to enforce their tastes upon millions of users and disrupt existing, productive, habitual user interface behavior.

And by the way, it's absolutely possible to securely run an instance of Firefox 28 in a read-only, sandboxed, firewalled VM, restricted to connecting to specific trusted hosts.

Permitting a third party to control and modify your behavior by enforcing automatic updates in a manner that does not match your schedule can be an insidious security hazard unto itself. Organizations like Mozilla, Google, Apple and Microsoft have no interest in and no concept of what might be hugely disruptive to their end users, nor do they necessarily have any concept of a given environment's actual security posture. They simply cry " _security_ " and then rampage all over everyone's shit with righteous entitlement.

Nope. I define my security practices (including whether I run a javascript- enabled browser at all), and I define my update schedule.

<comment><USER50> You should probably build your OS and all your software from scratch, cause it seems you have a problem with using software that doesn't meet your arbitrary guidelines.

</comment></comment></comment></comment><comment><USER57> This is my favorite firefox specific "bug", still around in 30 I would guess:

[http://jsfiddle.net/rk7ke/](http://jsfiddle.net/rk7ke/)

Works fine in literally all other browsers. Oh well.

<comment><USER58> nope, doesn't work in Chromium 36.

<comment><USER59> Nor in Opera 12.

</comment></comment></comment><comment><USER60> So I guess minor updates are how we do things now.

<comment><USER22> Yup! Release early, release often. Linux (kernel), Gnome, Ubuntu, Firefox, and Chrome (and lots more) are all on scheduled updates.

Edit: The advantage to rapid releases is that you can roll out minor updates when they're ready without having to wait for big ones, and you don't have to rush big ones for a deadline. If you miss one release, it's no a big deal because there's another one coming right up. Release when it's ready!

<comment><USER61> Rapid releases != rapid major version number increments. If you update the major version number too often it becomes meaningless.

The Linux kernel is on version 3.15, for example.

<comment><USER22> Yes, it is meaningless, and they intentionally hide the version number now - the download page doesn't even show it. But what could a major version number mean? GNU Emacs was on version 1.x for so long they dropped the leading "1." and promoted the minor version number to the major version. Ubuntu just numbers their releases after the date, e.g. 12.04 came out in April 2012.

<comment><USER61> Quote from Wikipedia that expresses my viewpoint on the subject:

> In principle [...] the major number is increased when there are significant > jumps in functionality such as changing the framework which could cause > incompatibility with interfacing systems, the minor number is incremented > when only minor features or significant fixes have been added, and the > revision number is incremented when minor bugs are fixed.</comment></comment></comment></comment></comment>


Notice of Security Incident - <AUTHOR> https://about.flipboard.com/support-information-incident-May-2019/ <comment><USER2> > If users created or changed their password after March 14, 2012, it is > hashed with a function called bcrypt. If users have not changed their > password since then, it is uniquely salted and hashed with SHA-1.

This is a common mistake.

Don't ever do _opportunistic_ upgrades. Instead, upgrade all at once and retain "legacy" metadata needed to re-authenticate the user until their password hash is rotated. [https://paragonie.com/blog/2016/02/how-safely- store-password...](https://paragonie.com/blog/2016/02/how-safely-store- password-in-2016#legacy-hashes)

Beyond that: Bcrypt is great, SHA1 is terrible, and the level of technical detail in this advisory is excellent. The fact that I was even able to critique their 7 years old security decision _at all_ speaks volumes to the transparancy.

<comment><USER3> I think their main mistake was requiring a user to change their password to upgrade the hash instead of upgrading the hash on the next user login.

<comment><USER2> What if there wasn't a "next user login"? You'd hold onto insecure hashes possibly forever.

Don't make this mistake. Rehash all of them up front.

The details of whether or not users are forced to change their password is irrelevant to the escape route from this trap.

<comment><USER4> How are you going to rehash them without having the cleartext password? Hash the SHA1s to bcrypt and then check every password's bcrypt and SHA1*bcrypt's password from then on?

<comment><USER5> It's explained in the linked blog post in the chain you're replying to, but:

\- Set all password hashes to Bcrypt(existing SHA-1 Hash)

\- Create a new flag column to track whether the password is upgraded to straight Bcrypt.

\- If flag is false, compare stored hash with Bcrypt(SHA-1(user input)). If it matches, log user in and replace stored hash with Bcrypt(user input). Set flag true.

\- If flag is true, compare stored hash with Bcrypt(user input)

<comment><USER6> I don't think that'd work in this case since the SHA-1 was salted, so you'd need to store the SHA-1 salt in a separate column, then calculate Bcrypt(SHA-1(input + salt)), right?

<comment><USER5> Obviously they had to be storing the salt to begin with, so yes you'd keep using that salt column and use user input+salt as the input to SHA-1.

</comment></comment></comment></comment></comment></comment></comment><comment><USER7> For an app that I no longer use, long since deleted and have forgotten about, hearing that there was a security incident that compromised my password is unsettling. I was relieved that I logged in to their app through twitter and my password wasn't store through them.

<comment><USER8> Same here, at least for the first part. I had used a plain email/password to sign up. After getting this advisory I reset my password and immediately deleted my account.

Nothing against Flipboard, and I appreciate the level of transparency here, but it's annoying to think that I created that account 7 or 8 years ago, haven't touched it since, and it's still there, with the potential to be a liability to me.

</comment></comment><comment><USER9> Bummer for the company and I wish them well as they navigate the incident response waters. What I found interesting from the article was

If users created or changed their password after March 14, 2012, it is hashed with a function called bcrypt. If users have not changed their password since then, it is uniquely salted and hashed with SHA-1.

They could have migrated all accounts regardless of whether they came back to the site or not, changed their password or not, etc. Just use:

password_hash = bcrypt(sha1(raw_password))

</comment><comment><USER10> What can someone use as a salt that is unique to a user that would not be in that record as plain-text and guess-able? Creation timestamp? email? username?

<comment><USER11> Just use a random value and store it with the hashed password. The salt is there to prevent an attacker from using a rainbow table to search your whole database for known passwords. Even if they have all your hashes and all your salts the fact the salts are unique forces them to attack each hash individually.

What you're looking for is a pepper [0]

[0] [https://en.wikipedia.org/wiki/Pepper_(cryptography)](https://en.wikipedia.org/wiki/Pepper_\(cryptography\))

<comment><USER10> Hmm, seems to me using both is optimal

horrible psuedocode follows...

      cryptchoice = len(username) % 3

      switch cryptchoice:
         case 0:
           pepper = pepper[1]
           salt = email

         case 1:
           pepper = pepper[0]
           salt = creation_time

         case 2:
           pepper = pepper[2]
           salt = username

      bcrypt(salt+password+pepper)

<comment><USER11> It's definitely wise to use both a salt and a pepper when hashing passwords. Don't bother with the switch statement, though, it's just security through obscurity. You're much better off keeping your security-related code as simple as possible so it's easier to notice bugs in it.

</comment></comment></comment></comment><comment><USER12> This just made for a good reminder I needed to close this account.</comment>


Fish and (micro)chips: Why I'm relatively relaxed about robots - <AUTHOR> https://bankunderground.co.uk/2016/10/10/fish-and-microchips-why-im-relatively-relaxed-about-robots/ <comment><USER2> TL/DR:

After 900 words, he realizes the question is when machines can exceed human intelligence. Then, he concludes that there's no way it can happen in 40-50 years[1], based on, apparently, _the opinion of a couple other economists_.

> Perhaps automation will be qualitatively different ... because robots will > have a cognitive function...

> But the million dollar question is whether this change in substitutability > will occur, and if so, how fast...

> Perhaps in the distant future robots might displace large swathes of human > labour. But unless there are rapid advances in medicine or time travel, I > fear I won't be there to see it…

[1] looking at his CV he appears to be 40ish, that's where I get an implied 40-50 year time horizon [http://www.bankofengland.co.uk/research/Documents/researcher...](http://www.bankofengland.co.uk/research/Documents/researchers/johnlewiscv.pdf)

<comment><USER3> Or alternative TL/DR:

Economist has read about the concept of the outside world.

</comment></comment><comment><USER4> This guy is delusional and ignores inconvenient facts. Such as there being limited fish, and a limited appetite for fish.

Congrats, John Lewis. In your attempt to convince me automation isn't going to be too disruptive, you've instead nudged me towards the opposing opinion.

</comment><comment><USER5> The problem is not automation of jobs. The problem is that developed countries don't need to consume as much as they used to. We can reallocate jobs until a certain point, but if we catch more fish that we need, we will eventually reach unemployment.

<comment><USER6> A league of fish catching nations, (who knows, maybe they will call themselves the Organization of Fish Exporting Countries, or OFEC) will form and they will control fish catching operations.

</comment></comment><comment><USER7> "Previous economy wide transformational changes didn't happen in a short space of time. "

Hmm yeah thats true. But since the industrial revolution there has been a lot of changes. Especially in the way of infrastructure and communication. Industrial revolution took 50 years, the advent of the smartphone has only taken 5 years.</comment>


Facebook down 8.5% in after hours on earnings  - <AUTHOR> http://finance.yahoo.com/q?s=FB

<comment><USER2> It seems shareholders are not impressed with Facebook's earnings.</comment>


Keeping the Startup Spirit Alive in a Growing Company - <AUTHOR> http://bits.shutterstock.com/2013/12/11/seven-keys-to-keeping-the-startup-spirit-alive-in-a-growing-company/ <comment> throwaway-bork Dan McCormick, the author of this piece, is the reason Shutterstock has a great engineering culture. He puts people before everything else, and finds a way to let all kinds of different personalities and talents shine. He brings out the best in people.

The fact that he was allowed to keep doing what he was doing during their run- up to an IPO seems noteworthy. Folks like him are often pushed out. Maybe he shines so brightly nobody would dare?

</comment><comment><USER2> A lot of what I read here reminds me of the Apple I joined 6 years ago. That's great to see other companies understand the value of small autonomous teams.

</comment><comment><USER3> >At Shutterstock, we've delayed the reversion to an uninspired >mean by letting different teams and groups in the company >develop their own culture.

I worked for a growing tech company over the last 2 years - and was there while it grew from 30 to 150 people. I found that this was one of the most important things to keeping things fun and engaging. It felt like there were a bunch of little startups within a bigger startup.

The only downside thought was that people had divergent ideas of what our company culture really WAS. We hadn't done the work that Shutterstock probably has in defining our overall company values, brand, ideals etc.

I'm going through the startup growth path again and I'm curious to see what other people have seen work in scaling cultures in growing companies. Any big insights or observations from the HN hivemind?

<comment><USER4> Spotify has a great article on this, if you haven't seen it: [http://ucvox.files.wordpress.com/2012/11/113617905-scaling-a...](http://ucvox.files.wordpress.com/2012/11/113617905-scaling- agile-spotify-11.pdf)

<comment><USER3> Thanks for sharing!

</comment></comment></comment><comment><USER5> I wonder what size exactly a "small" team is, especially if they contain "software engineers, Q.A. testers, user-experience developers and product owners." Somewhere around 25?

<comment><USER4> Nope, usually about 6 people: 2-3 devs, 1 tester, 1 UX, 1 PO.

<comment><USER5> Oh wow. How many teams do you think are at Shutterstock? And then how many teams can one manager manage basically? (just trying to get a feel for how the "middle management" starts to come up when the organization grows).

<comment><USER4> We have about 14 teams. The topic of management is a great one. We've shifted our approach over the years. That story might make a good blog article in itself. We've ended up with what's sometimes called a "matrix" structure, where people's day-to-day activities are based on what the team is doing, but each role (dev, tester, UX) reports into a manager (who's usually not on the team) with expertise in that domain. We've mostly avoided middle managers who only manage -- nearly all our managers are also on teams and, if they're devs, code. But we've also learned that having more than five direct reports can get pretty overwhelming, and so we've had to expand our org chart as we've grown for that reason.

<comment><USER5> Ok great, I think I understand that...but a full blog post would definitely clear it up (also I've finally figured out you're obviously at Shutterstock so can just ask direct questions).

Who decides what each team is going to be working on? Do tasks come down from the C-level guys, are you self-directed on what you want to work on, etc.?

<comment><USER4> Great questions! Each team has a specific domain -- we have a customer experience team, a contributor team, a search team, etc. Each team also has one or more stakeholders -- business folks that help set the high-level direction of the team. The teams work with their stakeholders (some of whom are super hands-on, others aren't) to pick 2-3 projects per quarter to focus on. We try to talk in terms of the problems each team should solve, and let the team itself work out the best solution.

It has taken us years to refine our process, and it's been a great journey. I'm happy to chat more about it with anyone -- hit me up at dan at shutterstock.com

</comment></comment></comment></comment></comment></comment><comment><USER6> Nice article. I particularly like the point about culture not changing... most startups definitely tend towards a more "corporate" feel as they grow which can suck the fun out of building cool stuff.

</comment><comment><USER7> Let's talk more about the whisky tasting culture.

<comment><USER4> What would you like to know? :)

</comment></comment><comment><USER8> Never let them fly business class

Part of the job is keeping the wrong people out. That's how to keep them out. Http://a.sarva.co explains why

<comment><USER9> I'm tall. When I fly for business, I get extra legroom / business class or don't go.

sfo -> nyc: i'm giving the company an absolute shit 16 (round trip) hours of my life. So they're going to pay some money to make me less uncomfortable, and if that's a problem, I don't go. Bosses tend to react poorly to flat out refusal to travel except when it's reasonably comfortable but that's their problem. If making me miserable (and unproductive; I can't even fully open my laptop in coach) to save $700 is a problem, then fuck 'em.</comment></comment>


Nextjournal: Environments - <AUTHOR> https://nextjournal.com/nextjournal/environments <comment><USER2> I'm one of the founders. The environments notebook includes the default environments you get when starting a notebook on Nextjournal. These are again built in Notebooks, see e.g. for [https://nextjournal.com/nextjournal/python- environment](https://nextjournal.com/nextjournal/python-environment) for a description of what our default Python environment contains and how it is built. This is again built on top of our bash environment, that's built on top of a stock ubuntu image: [https://nextjournal.com/nextjournal/bash- environment](https://nextjournal.com/nextjournal/bash-environment).

</comment><comment><USER3> I know it's 2019 and all, but is that 6MB image at the top really necessary?

<comment><USER2> It's not. Replaced it with a 600kb JPEG version, thanks!

</comment></comment><comment><USER4> "403 Client Error" after entering my email and clicking "get started"

<comment><USER2> Sorry about the glitch. Can you give it another try? You can use `xoxo` as an invite code for the private beta if it works this time.

<comment><USER5> just a heads up: An Impressum is rather hard to find even though you seem to be based in Germany (Berlin, assumption based on the "Sauspiel" connection) and with commercial interest.

<comment><USER2> Yes, we're based in Berlin. Should put the link to [https://nextjournal.com/imprint](https://nextjournal.com/imprint) back into the footer.

You can read about how Sauspiel – a community for the German card game Schafkopf – allows us to build Nextjournal on [https://nextjournal.com/about](https://nextjournal.com/about).

</comment></comment></comment></comment><comment><USER6> Since when is GitHUB a version control system?

<comment><USER2> Thanks, fixed.</comment></comment>


How much do coders make? Check out this data from around the country - <AUTHOR> https://gigaom.com/2014/10/18/how-much-do-coders-make-check-out-this-data-from-around-the-country/ <comment><USER2> Does anyone know the minimum sites I'd have to allow through RequestPolicy and NoScript to see the data on this site?</comment>


Reddit Is Being Manipulated by Big Financial Services Companies - <AUTHOR> https://www.forbes.com/sites/jaymcgregor/2017/02/20/reddit-is-being-manipulated-by-big-financial-services-companies/#1ea3aae84c92 <comment><USER2> With fake news, fake comments, and state sponsored reputation campaigns, what is real any more? It seems like the best strategy is to practice and preach "Think for yourself and make your own judgements about the world", now more than ever.

</comment><comment><USER3> Any marketers currently working to manipulate public opinion on HN through the use of sockpuppet accounts, upvote this comment.</comment>


Internal Microsoft video lampoons Google Chrome - <AUTHOR> http://www.geekwire.com/2013/internal-microsoft-video-lampoons-google-chrome/

<comment><USER2> As pointed out in the comments on the article: Google monetizing my web behavior doesn't deprive me of money, and also makes my ad experience "more positive" (less painful). It may also make me more likely to buy the products being advertised, but that is in no sense a fault - if there's a great deal on skis, or climbing gear, or something else I care about, I would far prefer to know about that than to see an advertisement for a <some demographic group> specific dating site.

</comment><comment><USER3> Personally Google scares me, and it's getting worse with each Google I/O.

The concern for me is Google seems like they will 'win' the game of software corporation. MS seem to be slowly tanking with little future in them unless they tear down their basic business practices, they seem destined to become a patent troll company. Their Windows 8 UI failure, mobile and tablets don't seem to be going well. Apple have their stuff but Google have the data and the backend and now they are basically placing themselves to do everything their rivals do.

Google have huge amounts of data and it's all locked away. Like how they where talking about user contributed Google maps on day1 keynote, they are asking the community to give them data for their financial gain. They are very good at using opensource to their advantage without giving anything that could rival them, for example Android, it's built on Linux but has their framework that basically makes it it's own OS. The dev is done in house so really the openness is very one way. Much of the useful stuff is propitiatory gapps. Everything is sold through the Google App store.

We have OpenStreet maps, why couldn't they have worked in with them? Or at least make community contributed stuff under a CC license. OSM also did the charity mapping stuff for disaster sites first, then Google came along and fragmented things with their own clone.

A lot their new maps stuff seems to be work done using peoples phone pictures.

I worry about what will happen if we get a real Google AI. That's basically a 'you win the computers'. AI could do away with an economy (at least on the individual level) and give us a utopia. Will Google at that point cease being a corporation and do things like open up their data and algorithms for public use and drop their tracking? Or will they keep their power, continue to slap ads on everything which will be sold via some kind of fake virtual currency.

Maybe if we have AGI we could just have it to make open versions of everything. Assuming we get AI other than from Google. Maybe their AI will be instructed not to aid in the creation of other AIs. Or even see legislation passed to required licensed AI creators with the AI already in existence enforcing it.

Having said all that, I much, much, much prefer a Google world to a Microsoft (sociopaths) or Apples (total control) ones.</comment>


Code_swarm. An experiment in organic software visualization. - <AUTHOR> http://vis.cs.ucdavis.edu/~ogawa/codeswarm/ <comment><USER2> You should really indicate in the title that this is a visualization of the commit history of people in famous open source projects.

But I was really taken away by it. I have new respect for the patience of language developers. They just keep plugging away!

<comment><USER2> Thanks to whomever modded the title. Saying 'WOW' just doesn't compare with describing why something is interesting.

The movie for the Eclipse project is incredibly beautiful. It's amazing to see so many people working so hard and so consistently on something.

My wish? A visualization, like this, of the wikipedia project -- all or parts of it.

<comment><USER3> A more modest real-time visualization I made some time ago: <http://www.lkozma.net/wpv>

</comment></comment></comment><comment><USER4> These visualizations are beautiful. What would make it considerably more interesting would be access to the code so we could run it against our own projects, or perhaps integration into something like <http://www.ohloh.net/>

<comment><USER5> Yeah, I was disappointed that he didn't have any code up for download.

I would have loved to have run that on corporate SCMs.

<comment><USER6> I too wanted to do this.

I keep finding my way back there just in case it opens up.

</comment></comment></comment><comment><USER7> What I thought was amazing was that there were really only about 5 developers that worked on Python until version 2.0 in 2000. Guido essentially plugged away at that project for 9 years with just a little help before it took off. Amazing.

<comment><USER8> I think there were more developers but a few of them had a right to commit. Guido could commit patches supplied by other people, therefore these people do not show up in the visualization.

</comment></comment><comment><USER9> This has so many good lessons in it.

First off dont' expect anything to take off without year __s __of hard work.

Second it takes about 10 years for things to really catch on in software,standards,technology.

Third, many times is is only the creator or a few people keeping large languages and frameworks alive.

Fourth, when you get hired at Google you are officially a rockstar if they use the language you created 10 years prior.

Go Guido go...this visualization is intensely inspiring, of course I am talking about the Python one the most.

</comment><comment><USER10> It would be nice to know what the algorithm is for the movement and location of developer names, since that isn't made clear on the project page. It seems to have something to do with the average location of the files when they light up and start flying. If that's the case, what's the algorithm for the location of the appearing files?

Without knowing some of the finer details of what is going on, I find it to be more entertaining than educational. Can we learn something other than a general idea and appreciation of the activity that went into a project?

<comment><USER11> Looks like they place dots around the edges of the screen (randomly) when the document is first committed. Then the physics model pulls in with some linear (to distance) force to developers that have committed to it. Developers repulse everything at a force square to the distance of the object, so that documents find equilibrium at a ring.

</comment></comment><comment><USER12> Very cool! One thing I didn't like was that the more important collaborators were impossible to read by the end, while the peripheral ones were easier to read, because they weren't jumbled up in the middle.

<comment><USER13> On the other hand surely that is an excellent visualization of thankless dedication and becoming something bigger than yourself. "Individuality is a bourgeoisie abstraction." -some crazy maoist postman (seriously).

</comment></comment><comment><USER14> Totally amazed. I would love to get this and import our SVN data for the last few years. Would be a great internal present to send to the engineering team.

</comment><comment><USER9> This is a very good use of visualization. Best thing I have seen in some time using it. Almost biological...

</comment><comment><USER15> I wish they did Drupal next :)</comment>


Ask HN: Invest in Sailfish OS? - <AUTHOR> Currently I'm searching for a new smartphone. And at the moment there are 4 OSes left: Android, iOS, Windows and Blackberry.
A lot of app makers are dropping support for Windows, and Blackberry is already putting Android on devices, so there are only two real options left.
But I have been following Sailfish for some years and to me it looks very promissing. Later this month Sony will add support for (all?) Xperia devices and Russia and China are also busy developing for Sailfish OS.
So I got the feeling Sailfish could become the third option in the near future.
What do you think? Could Sailfish be worth investing in? <comment><USER2> Sailfish, itself, is free. If you get a phone that's supported as part of Sony's Open Devices Program: [https://developer.sonymobile.com/open- devices/list-of-device...](https://developer.sonymobile.com/open-devices/list- of-devices-and-resources/) , you may be able to use it with both Sailfish and Android. Although, I expect that support for the more fancy components on the newest phones will take longest to arrive in Sailfish.

</comment><comment><USER3> Very unlikely in my opinion. The economic barrier to entry to bootstrapping a mobile ecosystem appear to be so high that extremely well funded efforts have floundered, I see very little reason why Sailfish will succeed where others have failed. List of failed efforts to jumpstart mobile ecosystems are - Creative (ziilabs), Microsoft (multiple efforts), Blackberry, Nokia (Maemo and Symbian), Ubuntu (Ubuntu phone).

<comment><AUTHOR> Maybe. But they have one pro: most Android apps also run on Sailfish.

</comment></comment><comment><USER4> Do Sailfish have their own app stores like PlayStore and AppStore? QT tooling for Sailfish is a bit hard sell than Kotlin and Swift were employed.

If Swift could run on Sailfish, it's even worth to invest.

<comment><AUTHOR> The app store can be found at [https://harbour.jolla.com/](https://harbour.jolla.com/)

It's also possible to develop Android apps that can run on both systems.</comment></comment>


Hosting your entire web application using S3 and CloudFront - <AUTHOR> https://www.sankalpjonna.com/posts/hosting-your-entire-web-application-using-s3-cloudfront <comment><USER3> Cloudflare + Backblaze B2 (or Wasabi) beats this hard. They are Bandwidth Alliance partners, so you won't incur egress traffic cost in B2 side. Cloudflare's Free plan is more than enough in most cases. Also B2 gives you free 10 GB storage when you sign up.

<comment><USER4> Cloudflare blocks Tor users unless they solve a Google CAPTCHA and accept cookies. By saving money you limit your audience and make the world a worse place.

[https://blog.torproject.org/trouble- cloudflare](https://blog.torproject.org/trouble-cloudflare)

<comment><USER5> > Users are either blocked outright with CAPTCHA server failure messages, or > prevented from reaching websites with a long (and sometimes endless) loop of > CAPTCHAs, many of which require the user to understand English in order to > solve correctly. For users in developing nations who pay for Internet > service by the minute, the problem is even worse as the CAPTCHAs load slowly > and users may have to solve dozens each day with no guarantee of reaching a > particular site. Rather than waste their limited Internet time, such users > will either navigate away, or choose not to use Tor and put themselves at > risk.

So, if we don't make our websites available in languages used by oppressed peoples, if we don't make sure it's very low latency, and if we try to filter out abusive users, we're making the world a worse place. Not just leaving the world in a bad state, but actively increasing the harm done to the world, just by making a website that not everyone can or wants to use.

Not only do I not buy this argument, it makes me want to support Tor less, if for no other reason than blatantly ignoring why the captchas were put up in the first place.

<comment><USER6> I agree with most of what you're saying but then I don't agree with your assertion that this makes you want to support Tor less.

The part you have a problem with, that it actively increases harm done in the world, wasn't even an assertion made by Tor.

</comment></comment></comment></comment><comment><USER7> Using CloudFront for a static website is a good choice if you really want to burn some cash with their outrageous bandwidth price.

Cloudflare free tier can serve terabytes of bandwidth for free. Add some cheap hosting or free tier EC2 or GCP and you are good to go.

<comment><USER8> CloudFlare is not free for business. The free tier is for hobby projects or individuals.

<comment><USER9> That simply isn't true. You can use our free service to run a business and many small businesses do. Larger businesses typically want things we only provide on the pay plans and therefore pay for the service.

<comment><USER8> That's good to know. The description of the free tier is a bit misleading:

      Free
      Cloudflare for Individuals is built on our global network.
      This package is ideal for people with personal or hobby projects that aren't business-critical.

<comment><USER10> Eh, seems like expectations management to me, i.e. "don't blame us if you do something business-critical on the free tier and it goes wrong and you didn't pay for support to get you out of it".

</comment></comment></comment></comment></comment><comment><USER11> Why do we need to make everything so complicated and fancy? I am not trying to be rude but I hate this trend of everything needs to be hosted on AWS and pay hundreds of dollars.

Why not dump these static files into a shared hosting? It shouldn't cost you more than couple of bucks a month.

You get SSL, Email, sub-domains, SSL, logs and much more for couple of bucks a month.

<comment><USER12> The article explains how to do it without complicating it with shared hosting, and it only cost $.8/mo for 100k visits.

Not knowing something doesn't mean its complicated, it just means it is unfamiliar, for you. Once you did this several dozen times, its the simplest thing ever.

<comment><USER11> With AWS, your costs are unpredictable. You could be spammed or some search bots decide to go haywire and you will incur hundreds of dollars.

The second thing is AWS is very expensive for what it does. Do you need to add DNS records? There is Route 53 which costs extra. Do you need emails? There is AWS Simple Email which costs extra. Do you need logs? The storage cost (although little) is added to your bill. Do you need databases? Do you need support?

All I am saying is that shared hosting should be first considered for static websites.

<comment><USER13> Yes and no.

Flip it around. AWS let's you not pay for things you don't need. Then, if there's a biz requirement for something else, you make that _investment_.

Of course there are alternatives. But shared hosting is a roll of the dice. For a hobby project or POC? Sure, start with shared. But if you're certain shared is not a semi-longer term option don't wasteyour time. Shared is cheap for a reason. Saving a couple dollars will dry up quickly in downtime and headache time.

</comment></comment></comment></comment><comment><USER14> For the past several years I've been running a 100% static web application that serves rain radar images. It also updates itself periodically using serverless functions currently running on AWS Lambda, but can easily run anywhere else.

This is a very stable architecture for such websites and it's great to see it being widely adopted.

I've written more details about the Rain Radar application in this blog post: [https://yuv.al/blog/an-architecture-for-periodically- updatin...](https://yuv.al/blog/an-architecture-for-periodically-updating- static-websites/)

<comment><USER15> I recently turned years of data into $$$. Keep archiving it.

<comment><USER16> Yes, please. Do tell.

<comment><USER15> Not too dissimilar to what OP was talking about

</comment></comment></comment></comment><comment><USER17> Nice, but the article leaves out the bit about where the API is hosted. It really isn't the entire web application, just the easy part.

Still a nice guide for static website owner.

<comment><AUTHOR> Hello, author here.

My bad for not giving a more appropriate title for the post. You re right this setup does not take the backend APIs into account. In our case we use Lambda for the backend APIs so that is also serverless but I failed to mention it in the post.

<comment><USER18> Hi, also curious how you integrated WhatsApp messages to user for confirmation? Is it business api and is the pricing an issue? (I'm in India too and think WhatsApp api is a bit expensive especially for a use case where I initiated the messaging like in your case)

</comment></comment></comment><comment><USER19> Or you can just use free Netlify tier

<comment><USER20> One big advantage of Netlify is the automated deployment of pull requests into their own dedicated environment.

It's so nice to be able to review a PR not only based on its code, but also by having a look at the built website.

<comment><USER21> You can do this in AWS with Amplify Console as well.

<comment><USER20> Also with a regular Cloudfront distribution? I don't want to use Amplify, I just need the PR-preview feature.

</comment></comment></comment></comment><comment><USER22> I did find one catch with the S3/CloudFront approach, relating to default document, when I was looking at hosting a static Hugo site a few months ago. With S3 web hosting, you can specify a default object which also works for subdirectories (e.g. so [http://www.example.com](http://www.example.com) returns [http://www.example.com/index.html](http://www.example.com/index.html) and [http://www.example.com/foo](http://www.example.com/foo) returns [http://www.example.com/foo/index.html](http://www.example.com/foo/index.html)). With Cloudfront, the default document doesn't apply to subdirectories, which would have broken my site.

(For the author of this article, it looks like the combination of CLoudFront's default document and custom error handling did the job for their site - <USER2> flagging this as something to look out for in cases where it doesn't work :-) )

AWS suggest a workaround using Lambda@Edge ([https://aws.amazon.com/blogs/compute/implementing-default- di...](https://aws.amazon.com/blogs/compute/implementing-default-directory- indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/)) to rewrite the requests at the CloudFront layer - but at that point I decided that actually getting the site published was more important than adding more to the technology stack, so it's now happily hosted on Netlify's free tier.

<comment><USER23> there's a better and simpler workaround; there are two ways of setting up CloudFront->S3 origin. One is to use the S3 as file storage, the other is to use the S3 web site endpoint as a HTTP origin. With the second option, index documents work with directories, as well as S3 redirect rules etc. CloudFront sends S3 a http request as if it were an external web site, but it's all inside AWS so in effect your costs are the same in both options.

<comment><USER22> Thanks for that - I certainly agree that's simpler than Lambda@Edge, and option well worth considering.

I looked at that approach at the time but didn't go down that route because, as far as I understood (unless I missed something), that would involve having the S3 bucket directly publicly accessible over HTTP (not HTTPS) with the S3-style URLs, including public access. And my main motivation for adding CloudFront to the mix was to support/enforce TLS - I certainly didn't have traffic levels requiring it!

(But, pragmatically, the key risks of someone going to the effort of finding and using the unpublished S3 URL would seem to be be that (a) the site could stop working if I change the hosting and (b) they, through their own choice, aren't using TLS - which, for a static, low-traffic, personal blog, could be considered pretty low.)

</comment></comment></comment><comment><USER24> You can do a very similar thing with CloudFlare and any free/cheap backing store (e.g. S3, Github Pages, etc).

<comment><USER25> Yes, plus Cloudflare is free for unlimited traffic. I use it in front of App Engine, and I've served 1m pages in a day for $0 because I don't even hit the App Engine free tier limits after Cloudflare's cache takes the traffic.

<comment><USER26> > _Yes, plus Cloudflare is free for unlimited traffic._

Subject to fair use (which is fair). [https://webmasters.stackexchange.com/questions/88659/how- can...](https://webmasters.stackexchange.com/questions/88659/how-can- cloudflare-offer-a-free-cdn-with-unlimited-bandwidth)

<comment><USER3> What about the Workers?

<comment><USER26> Matthew Prince is on-record that Cloudflare Workers are an exception to (unspecified) bandwidth limits in that you're free to use a very large amount of it without having to pay for their Enterprise / Pro / Business plans.

See: [https://news.ycombinator.com/item?id=20791660](https://news.ycombinator.com/item?id=20791660)

</comment></comment></comment></comment></comment><comment><USER21> I'd highly recommend looking into Amplify Console for hosting static sites on AWS.

Behind the scenes you're still running on s3/cloudfront so you don't need to worry about scalability, but you'll get automatic https, build and deploy pipeline hooked into your github repo, per branch environments, etc.

</comment><comment><USER27> I have similar setup but fully automated with GitHub an travis. I use cloudflare instead of cloudfront to reduce cost as well - [https://reisinger.co.uk/posts/s3_hosting/](https://reisinger.co.uk/posts/s3_hosting/)

</comment><comment><USER28> If you want to host a static website on AWS with one command, and not clicking around in the Console, have a look at [https://github.com/tobilg/serverless- aws-static-websites](https://github.com/tobilg/serverless-aws-static-websites)

For fullstack websites, I created [https://github.com/tobilg/aws-fullstack- website](https://github.com/tobilg/aws-fullstack-website) which will additionally create a API based on API Gateway and its HTTP API feature

</comment><comment><USER29> For anyone thinking to simply host assets in S3 (i.e. skip the Cloudfront part), please do not. I'm not sure if it's my ISP throttling it, or the routing, but from where I am in Europe, accessing a file from an S3 bucket in us-east often results in speeds less than 100kbit/s. The same files served from Cloudfront will saturate my connection (gigabit).

</comment><comment><USER30> Am I missing something? This is not "your entire web application" \- this is the static piece of it, it still requires an application server doing the dynamic stuff via XHR.

Bad title. Should say "how to host the frontend to your SPA for pennies on CloudFront + S3"

</comment><comment><USER31> You should take a look at Amplify ([https://aws.amazon.com/amplify/](https://aws.amazon.com/amplify/)), it will make the whole process considerably less painful, allow you to easily access AppSync (graphql) and Lambda with your code all in one place, then also trigger rebuilds on git commits.

<comment><USER32> Too much vendor lock-in.

<comment><USER33> Could you give examples where vendor lock in becomes a problem?

Ideally something practical (as opposed to theoretical) or something from personal experience.

I generally agree but I feel that more details could be useful.

<comment><USER34> Any time you want to leave that vendor. If they up their prices greatly, reduce service levels, refuse to give attention to improving service levels.. break a clause in the contract... an so on.

<comment><USER35> While this is true in theory, I don't recall a single instance of AWS increasing pricing or reducing service levels - not saying that is impossible, but it hasn't happened so far (at least that I remember)

</comment></comment></comment></comment></comment><comment><USER36> I actually wrote a guide on this before that goes into a bit more detail and adds in some CD pipeline stuff with it

[https://dev.to/shane/how-to-create-an-aws-s3-hosted- angular-...](https://dev.to/shane/how-to-create-an-aws-s3-hosted-angular-app- with-a-custom-domain-https-and-continuous-deployment-2i3i)

</comment><comment><USER37> Deploying is also easily scripted using the aws-sdk package, see the docs for .S3 and .Cloudfront. Be aware though that if you have a large amount of files the the cost of invalidations at cloudfront will add up quickly, but you can how ever cherry pick files to invalidate.

</comment><comment><USER38> There is [https://apex.sh/up/](https://apex.sh/up/) Great tool for doing this and more.

</comment><comment><USER39> As far as I can see, it is possible for all internet users to see customers orders and addresses using this technique.

Did I miss something or is this a real problem?

<comment><AUTHOR> Yes but each order has a unique ID which only the customer who placed that order will have access to. If that customer decides to share that URL on his own discretion that is fine by us

</comment></comment><comment><USER40> With S3+CloudFront, has anyone been able to get www->root redirect to work with https? I like the setup otherwise.

</comment><comment><USER41> This is a great guide, thanks for sharing!

<comment><AUTHOR> Happy to help :)

</comment></comment><comment><USER42> How do you handle CSRF with static hosting?

<comment><USER43> CSRF is only needed when you have a dynamic website, when someone can potentially make a request on behalf of someone else (and thus make some malicious changes). If your website is 100% static, there's nothing to change.

</comment></comment><comment><USER44> What WhatsApp messaging API are you using?

<comment><AUTHOR> We use twilio.com for the WhatsApp API

</comment></comment><comment><USER45> Github pages is free and simple to use.</comment>


Which is better on Android: divide by 2 or shift by 1? - <AUTHOR> https://jakewharton.com/which-is-better-on-android-divide-by-two-or-shift-by-one/ <comment><USER2> Thorough work. Going back to the premise, I want to offer an alternative viewpoint by asking whether, in the case of binary trees implemented by arrays, "integer division by 2" of the array index is necessarily the best interpretation of what you are trying to do here?

Instead, you can also see the array index as a bit string, where every bit tells you which path to go down, left or right. In that case, "shifting right by one bit" moves you up to the parent. "Shifting left" moves you down to the left child. Flipping one bit flips you over to the other child. Bit wise operations indeed seem more natural with that interpretation.

A lot of "power of 2" multiplication/division has similar interpretations. For example, when walking page tables, you could see walking down the levels as "dividing by the size of the granule", or simply as "shifting right to select the index on that level".

No contest on anything where the power of 2 is coincidence, i.e. for non "computery" things where there is no such underlying structure.

<comment><USER3> I had a slightly similar experience at work. We deal a lot with angles and binary angles are often the most efficient representation. Many colleagues find it annoying because they insist on converting every binary angle to radian or degrees, but if you actually interpret the bits as successive divisions of a circumference, I actually find the binary representation way more intuitive than a floating point number.

<comment><USER4> That method is exactly equivalent to using revolutions as the unit with a fixed-point numeric representation. Maybe your skeptical colleagues would find that perspective more palatable?

<comment><USER3> That's some good advice. Unfortunately, most of the people I work with do not have a computer science background (they are materials scientists and mechanical engineers), so they are not familiarized with fixed-point arithmetic neither.

</comment></comment></comment></comment><comment><USER5> I appreciate the thorough exploration and resulting detail in this article. Still, I find it a little sad that either the state of our toolchains or the perception thereof prevent it from being self-evident that basic strength reduction will always happen, and developers need not worry about the cost of expressing simple arithmetic operations in the clearest way.

<comment><USER6> I would go further in that many programmers don't understand the difference between logical and arithmetic operations and why they exist.

I have had to puzzle over far too much code doing adds/subtracts/multiplies/divides instead of and/or/xor/shift _FAR_ too often.

I blame Java not having an unsigned type. There are apparently some weird tricks you can do with arithmetic in Java that operate on things like an unsigned type without having to go up to the next higher integer width.

<comment><USER7> What exactly do you miss in Java? It's possible to treat int as unsigned for all the necessary operations.

<comment><USER8> plus Java's had various unsigned integer operations on Integer for years

</comment></comment></comment></comment><comment><USER9> Question from a perf noob: it seems like this in principle only shows that there's no difference for a Pixel 3 because other Android machines could have processors that have/lack an optimization for shift or divide. Couldn't a different Android phone have different performance characteristics?

<comment><USER10> It is not that the processor that contains an optimization per se. The thing to understand is that shift is fundamentally a simpler operation than multiply... a shift can be implemented with a few transistors per bit and done in a single cycle trivially. A multiply unit takes tons of transistors, and often takes multiple cycles (this is a trade off you make when you design a multiply unit, you can save space by making it work on smaller integers and reusing it multiple times over several cycles to do multiplies of larger integers, just you like you iteratively multiply digits one you do it on paper by hand). Even on processors that have single cycle multipliers it takes a lot more power to do a multiply than a shift because of all the extra hardware you need to engage.

Since shifts are fundamentally simpler than multiplies it always makes sense to do this transform. This is one of a number of transforms that are generally called "strength reductions" <[https://en.wikipedia.org/wiki/Strength_reduction>](https://en.wikipedia.org/wiki/Strength_reduction>), converting for a more general expensive operation into a more constrained cheaper operation. In this case it is the equivalent to knowing that if you want to multiply a number by 10 you can just add a 0 at the beginning instead of having to write all the work by hand.

The only reason not to do this transform would be if you had a CPU that literally does not have a shift operation, but I cannot think of any such part. Even if you did have such a part, the odds are you could emulate a shift using other other instructions and still outperform the multiply.

This has been a standard optimization for half a century. The original C compiler for the PDP-11 did these transforms even when you turned off optimizations <[http://c-faq.com/misc/shifts.html>](http://c-faq.com/misc/shifts.html>).

<comment><USER11> > This has been a standard optimization for half a century. The original C > compiler for the PDP-11 did these transforms even when you turned off > optimizations

Consider this, a common easily applied optimization that compilers have been doing for half a century MAY have made it's way into modern CPUs.

Transistors aren't nearly as power hungry as you paint them and CPUs aren't nearly as bad at optimization. There is no reason to switch a multiply or divide for a shift. The ONLY reason to make that switch is if you are dealing with the simplest of processors (Such as a microwave processors). If you are using anything developed in the last 10 years that consumes more than 1W of power, chances are really high that the you aren't saving any power by using shifts instead of multiples. It is the sort of micro-optimization that fundamentally misunderstands how modern CPUs actually work and over estimates how much power or space transistors actually need.

<comment><USER12> Since it's what I'm typing this on, let's look at Skylake.

Multiply: Latency 3, Throughput 1 Shift: Latency 1, Throughput 2

If the ALU contained an early out or fast path for simpler multiplies, the latency would read 1-3. You can verify this by looking at div, which does early out and has a latency of 35-88.

Any compiler that doesn't swap a multiply to a shift when it can is negligent.

[https://www.agner.org/optimize/instruction_tables.pdf](https://www.agner.org/optimize/instruction_tables.pdf)

</comment></comment></comment></comment><comment><USER13> I am really struggling to understand the benchmark output quoted.

Can anyone elaborate what does benchmark=3/4 ns mean, and the count? Is the set-up part of the benchmark (test structure suggest not, but just to make sure)?

The only way I can read it is that 4000 divisions takes 4ns, and 4000 shift- rights takes 3ns, but that only has 1 digit of precision, which makes it unusable for comparison, but even then suggests a 25%/33% difference, which is not insignificant.

Also, the VM seems to optimise multiply out, so it must be doing it for a reason.

<comment><USER14> It's definitely not 4000 divisions per 4ns — that'd imply a terahertz computer. I think it's saying that the amortized cost of 4000 divisions is 4ns per division. Small integer division is an "easy win" for a dedicated HW path, so it doesn't surprise me that it's only a little slower than a shift-right. Variable length right shifts aren't that fast.

<comment><USER15> It's not small integer division that is being benchmarked, the JIT compiler has reduced it to an addition, a conditional move and a right shift. This sequence is then benchmarked against the right shift.

<comment><USER16> ART is an AOT complier, is it not?

<comment><USER17> It's both AOT and JIT.

[https://source.android.com/devices/tech/dalvik/jit- compiler](https://source.android.com/devices/tech/dalvik/jit-compiler)

<comment><USER18> With a PGO cache updated across execution runs and devices (since Android 10 PGO data is shared across the Play Store).

<comment><USER19> For anyone like me wondering what a PGO is: [https://source.android.com/devices/tech/perf/pgo](https://source.android.com/devices/tech/perf/pgo)

</comment></comment></comment></comment></comment></comment></comment><comment><USER20> Now I'm wondering if there's a power usage difference between the two.

It stands to reason that if two operations take the same amount of time, but one requires more transistors to compute, power usage should diverge.

<comment><USER21> For scalar instructions, most of the energy is consumed in scheduling not executing them. This means that cycles is a good proxy for total energy.

</comment></comment><comment><USER22> Everyone is talking about this microoptimization on the math of the access but all I can think about is how the data structure you are building using this is probably memory bandwidth limited and powers-of-two storage is almost definitely going to cause some kind of cache line aliasing, so maybe you should try something non-obvious like "division by 3" (after doing three key comparisons instead of one) and see if it makes your algorithm much much faster than messing around with a division by 2; there was even some good analysis of this effect a while back I can reference.

[https://pvk.ca/Blog/2012/07/30/binary-search-is-a- pathologic...](https://pvk.ca/Blog/2012/07/30/binary-search-is-a-pathological- case-for-caches/)

</comment><comment><USER23> Am I mis-reading this? The article keeps claiming there is no difference but the way I read it the compiler(s) are transforming mul/div to shifts. i.e. it very likely _is_ faster on the hardware but it won't matter for this particular toolchain because of the conversion.

<comment><USER24> > Am I mis-reading this? The article keeps claiming there is no difference but > the way I read it the compiler(s) are transforming mul/div to shifts. i.e. > it very likely is faster on the hardware but it won't matter for this > particular toolchain because of the conversion.

There is no difference... because of the conversion.

<comment><USER23> Right: for now, in certain situations, on the tested toolchain.

Even ignoring those caveats, several commentators seem to have got the impression that this applies to the CPU.

<comment><USER25> These types of transformations are simple to detect, well known, and applied by ~every compiler.

Unless you have evidence otherwise (ASM differences or benchmarks), there is no use in manually transforming your arithmetic into something more complex but faster. The compiler will do it for you.

<comment><USER23> I think that's a point which is bordering on religious - many people would debate trusting the compiler, especially over time and more complex situations.

I'd certainly tend to agree with you in general but more for the reason that the compiler can abstract over hardware changes across time. I'd take that benefit over the risk of the optimisation not being applied for most code I write - non-optimisations would be considered bugs and probably/eventually fixed.

I'd strongly disagree the code is more complex (in this case).

<comment><USER26> It especially seems religious to me because it's saying that somehow "/ 2" is simpler than ">> 1" because it has one less character for the symbol, and because division is a more commonly known operator to most people than bitwise shifting.

It seems to me that they are equally simple if we assume that programmers dealing with low level or performance intensive code know what a bitwise shift is and ignore the extra character, then they are literally equivalently complicated expressions with 1 symbol and 1 value applied to the symbol.

<comment><USER27> Code does not happen in a vacuum. Which is more understandable/simple depends on the domain of the code in question. Usually that's going to be the multiply or the divide.

<comment><USER26> Right, but my statement was that the domain would be low level or performance intensive code -- do you disagree that in that domain they are equally simple?

</comment></comment></comment></comment></comment></comment></comment></comment><comment><USER28> Another fast way to double a number is to add it to itself.

<comment><USER29> Isn't that the wrong direction for the optimization? I would assume you would want to compile adding two numbers into shifting by one, not the other way around.

(I know nothing about hardware, it just intuitively seems like moving a bunch of bits over by 1 should be faster than dealing with xor and carries)

<comment><USER30> In hardware terms, adders are simpler than shifters. You can usually do both in a single cycle, but it's going to be lower power to do the add instead of the shift.

To put this in more concrete terms: an N-bit adder involves N 1-bit stages to add each bit, and then a 1-bit carry network on top of that, which has N stages in it. So overall, it's O(N) in terms of hardware. An N-bit shift unit is going to use lg N N-bit muxes--or O(N lg N) in terms of hardware. Total gate delay in both cases is O(lg N), but adders have O(N) hardware (and thus energy consumption) while shifters have O(N lg N).

A secondary consequence of being larger area is that a superscalar architecture may choose to have one execution unit that has an adder and a shifter and a second that only has the adder. So an addition may schedule better than a shift, since there are more things it can execute on.

<comment> Tuna-Fish > To put this in more concrete terms: an N-bit adder involves N 1-bit stages > to add each bit, and then a 1-bit carry network on top of that, which has N > stages in it. So overall, it's O(N) in terms of hardware.

O(N) adders cannot meet the latency demands of modern high-frequency CPUs. The actual complexity of adders in real CPUs is usually O(N²).

</comment></comment></comment></comment><comment><USER31> He did this in Java? In one case, running on an emulator? That's removed too far from the hardware for this kind of benchmarking. Try in a hard-compiled language.

Using shifts for constant divide has been a compiler code generator optimization for decades. This is not something programmers have needed to worry about in source code for a long time, unless targeting some small microcontroller that lacks fast divide hardware.

<comment><USER18> Java is a hard-compiled language on Android since version 5.0.

ART, which replaced Dalvik on 5.0 (available as experimental on 4.4), was AOT only up to version 7.0.

As it was proven that Android users lack the patience of a C++ developer when updating their apps, Google adopted another approach with version 7.0.

A multi-tier compiler infrastructure, composed by a very fast interpreter hand written in Assembly for fast startup, a JIT compiler for the first optimization level, with gathering of PGO data, then the AOT compiler runs in the background and when the device is idle gets that PGO data and just like a C++ compiler with PGO data, outputs a clean AOT compiled binary for the usual user workflow.

In case of an update or changes in the workflow that trigger the execution of code that wasn't AOT compiled, the process restarts.

As means to reduce this kind of de-optimizations, since Android 10 those PGO files are uploaded into the Play Store and when a user installs an application that already has PGO data available, it is downloaded alongside the APK and the AOT compiler can do its job right from the start.

In any case, he used _dex2aot_ which is the AOT compiler daemon on Android.

Microsoft has gone through similar process with .NET for UWP, with the main difference that the AOT compiler lives on the Microsoft store and what gets downloaded is already straight binary code.

Apparently mixing language capabilities with toolchains keeps being an issue.

</comment></comment><comment><USER32> How come the division is almost the same as the shifting? Is the CPU pipelining the operations between iterations of the loop or something? There is a direct data-dependency in those operations but not between iterations so perhaps that's it?

AFAIK there's no fused add-shift op that could be used.

</comment><comment><USER33> Given the number of execution loops. The profiler applied an optimization. Don't expect this optimization during initial executions or seldom used code or cases where properties of the method do not allow it to be optimized; be it on Android VMs or JVMs.

</comment><comment><USER34> Apart from the fact that compilers are really good and generally will choose the best option for you, it seems like it boils down to what processor is used. On Android aren't ARM processors the most common?

<comment><USER18> Yes, followed by some Intel and MIPS survivors.

</comment></comment><comment><USER35> If it's signed int, unless you know the value is positive you can't just shift right 1--if the result of the shift is negative, you have to add 1.

<comment><USER24> Can't you do an arithmetic shift-right? That takes the sign into account.

<comment><USER30> No. An arithmetic shift right does a division that rounds down; an integer division operation instead truncates (rounds to zero). The easiest example is -1 / 2: -1 / 2 is 0, but -1 ashr 1 is -1.

To replace a signed division with ashr, you have to know that for all negative inputs, the value of the bits shifted out are all 0.

</comment></comment></comment><comment><USER36> I thought this discussion was settled 30 years ago?

Write what you want to do, not how to do it. There is no difference.

</comment><comment><USER37> ...So the Dalvik VM sucks?

<comment><USER18> Yes it sucks, that is why it was replaced by ART on Android 5.0.

<comment><USER37> Ah, i haven't kept up. Anyway, a right bit shift should absolutely be quicker than floating point or even integer division. If it isn't, that is an implementation problem.

<comment><USER18> ART as of Android 10, combines an hand written interpreter in Assembly, a JIT compiler that generates PGO data as well, and an AOT PGO based optimizing compiler capable of doing bounds check elision, de-virtualization, auto- vectorization, escape analysis and a couple of other traditional optimizations.

The PGO metadata files also get shared across devices via the Play Store as means to steer the AOT compiler into the optimal level of optimization across all users of the application.

I assume that at the current level of ongoing ART optimizations, the team would consider that a compiler bug.

<comment><USER37> Awesome info! Thanks!

What would you recommend for an IDE? I used Eclipse some years ago. Is that still common?

I may want to experiment with some Android flavored Java again.

<comment><USER18> Android Studio is the official IDE, it is a merge of InteliJ with Clion and Google specific plugins.

</comment></comment></comment></comment></comment></comment><comment><USER38> Is there an advantage of using multiply by .5 versus divide by 2?

<comment><USER39> Multiply by 0.5 would be slower, as it's a floating point operation rather than simple arithmetic.

</comment></comment><comment><USER40> if these kinds of optimizations make a difference for your applications write it in native code, dammitl

<comment><USER18> Which pretty much means Assembly, given that Java and Koltin go through JVM and DEX bytecodes to machine code, and C and C++ on Android go through LLVM bitcode to machine code.

</comment></comment><comment><USER41> TLDR: it is the same, like it should.

We are in 2020. Don't shift by 1 instead of /2 if you mean to /2.

<comment><USER42> lol... if you care about optimizing, you should care about all possible optimizations... (even if most of today's platforms don't)

<comment><USER41> Yeah but you should also then understand what will yield real results, and >>1 instead of /2 has become useless to write manually a long time ago, whereas e.g. continuous memory is more important than ever. You will not optimize a lot by attempting micro techniques from 30 years ago.

Other random example: in some edge cases, integer division replacement by a multiplication _can_ still be relevant today (depends on if its a constant, the compiler, and if nothing optimized also on the exact processor, though, because last models are already ultra-fast with the real integer divide instructions), but I suspect in 15 years (maybe even 10) this will be completely irrelevant, at least for high perf targets.

</comment></comment></comment><comment><USER43> News at 11 - someone learned strength reduction exists, which have been in use for the past 4 decades.

<comment><USER2> Had you read the article, you would have known that the question answered here was whether, and where in the process, strength reduction was actually applied.

</comment></comment><comment><USER44> A few points.

1\. Looking at the Java bytecode is practically meaningless, you would have to look at the machine code the JIT is creating.

2\. A division by 2 is identical to a shift right by 1 only if the integer is unsigned. Java integers are signed. Try this program in C to see for yourself:

int foo(int a) { return a/2; } int bar(int a) { return a>>1; }

Run gcc -S -O2 to get assembly output in text form.

Basically, the problem is this:

5/2 -> 2 (ok, rounds down)

5>>1 -> 2 (ok, same)

-5/2 -> -2 (ok, rounds down)

-5>>1 -> -3 (oops!)

3\. The question is really about the JIT backend for the target platform, which means CPU platform, not OS platform. So "on Android" does not make much sense here, as Android exists for x86 and ARM and those JIT backends might behave differently.

<comment><USER2> All things directly addressed by the article.

</comment></comment><comment><USER45> Honestly, it's hard to read this article and not question the author's mental state or intelligence.

He literally presents x86 and ARM assembly dumps where shift right generates one instruction, and divide generates that same instruction plus several others.

Then, he feels the need to run an unnecessary benchmark (most likely screwing it up somehow) and concludes there is no difference!

But how can there possibly be no performance difference, in general, between the CPU running an ALU instruction and running that same instruction plus several other ALU instructions?!?

It's almost unbelievable.

As to how he screwed up the benchmark, my guesses are that either he failed to inline the function (and the CPU is really bad), or failed to prevent the optimizer from optimizing the whole loop, or didn't run enough iterations, or perhaps he ran the benchmark on a different VM than what produced the assembly (or maybe somehow the CPU can extract instruction level parallelism in this microbenchmark, but obviously that doesn't generalize to arbitrary code).

<comment><USER46> While I think that there is merit to your argument, I feel like it could have been presented without questioning the author's intelligence or mental state.</comment></comment>


Building Dropbox's New User Experience for Mobile - <AUTHOR> https://tech.dropbox.com/2014/08/building-dropboxs-new-user-experience-for-mobile-part-1/

<comment><USER2> I really enjoy the new user experience on mobile these days. Really intuitive and works well with native Android features. Particularly think adding new files (multiple at once) has gotten a lot easier. Haven't had a chance use the new sign-up form but it looks great.

</comment><comment><USER3> Interesting how they use QR codes to tie-up the installation flow.

<comment><USER4> I agree. Also, that's a pretty awesome looking QR code.

<comment><USER5> It's actually five QR codes, and some probably meaningless junk in between.

<comment><USER4> Wow, I missed that the first time. Looking at it now, they pop out immediately.

</comment></comment></comment></comment><comment><USER6> I stopped using Dropbox after they hired the notorious war-criminal: Condoleezza Rice.

</comment><comment><USER7> Hopefully they build a way to view an entire long filename on the ipad version.

Not impressed with their current mobile offerings.

<comment><USER8> I gave up on Dropbox on ipad ever since using Bittorrent Sync. Dropbox started forcing me to keep their app open (to sync). Not going to happen. Bittorrent sync works like a charm to get the photos/videos off of ipad. I don't see a need for Dropbox anymore.

<comment><USER9> Bittorrent sync needs to add QR code support to their desktop app so you can get the sync secrets off a device easily.

They also need a more 1-way process, something which will only forward version new files.</comment></comment></comment>