TinyPilot: Month 33

Michael Lynch

TinyPilot:第 33 個月

一句話總結

緩步轉向第三方物流履行

重點回顧

  • 我已開始將 TinyPilot 的出貨履行轉移至第三方廠商的流程。
  • TinyPilot 顧客對價格的敏感度比我預期的還要低。
  • 我在 TinyPilot 的舊換新方案上投入大量資源,但不確定是否划算。

目標成績

每個月月初,我都會訂下當月想完成的事項。以下是本月目標的達成情況:

將低銷量產品的出貨作業轉移至新的 3PL(第三方物流)

  • 結果:我們的 3PL 廠商已連續三週負責處理 Power Connector 的訂單出貨。
  • 評分:A

過程中有些小細節需要磨合,但我們已成功轉移第一項產品。

NERD Summit 2023 發表演講

  • 結果:我已完成演講,且對自己的表現感到滿意。
  • 評分:A

自 2019 年以來首次親自回到 NERD Summit 感覺很棒。現場有許多精彩的演講,也有愉快的走廊交流。

減輕出貨團隊的負擔,使被動應對型工作占比低於 80%

  • 結果:大致上算是成功,但難以量化衡量。
  • 評分:B

為了轉移至 3PL,我們需要讓在地團隊空出足夠的工作量,以便多生產一週份量的裝置。我們採取了多項措施來減輕他們的負擔,不過他們的工時仍比平常多。

TinyPilot 數據統計

指標2023 年 2 月2023 年 3 月變動
不重複訪客12,1417,443-4,698 (-39%)
總瀏覽次數23,11717,904-5,213 (-23%)
銷售營收$72,585.15$86,803.78+$14,218.63 (+20%)
企業訂閱$290.70$290.700
權利金$3,935.73$4,820.75+$885.02 (+22%)
總營收$76,811.58$91,915.23+$15,103.65 (+20%)
獲利$32,905.55$43,952.10+$11,046.55 (+34%)

將 TinyPilot 的外殼從塑膠改為金屬後,需求大幅增加。即使我調漲價格並將行銷預算降至近乎為零,銷量仍持續成長。

我今年的目標是獲利達到 10 萬美元,但我們已經完成了 75%。照這個速度,我們將在 4 月底前就達到全年 10 萬美元的獲利目標。

轉向 3PL 廠商過程中的波折

我的首要任務是將 TinyPilot 的出貨履行轉移至第三方物流(3PL)廠商。3PL 的工作是在其倉庫中存放成品,並在接到訂單時進行揀貨、包裝與出貨。

為了啟動這個流程,我們先將銷量最低的產品——TinyPilot Power Connector 交給 3PL。這款產品是提供給自行組裝 TinyPilot 裝置的使用者,我們並未在官網上宣傳,每月僅售出 20 至 30 個。

Power Connector 提供了一個低風險的方式,讓我們在將所有訂單轉移給 3PL 之前,先進行端對端的測試。這次演練發現了好幾個問題,因此我很慶幸我們是從小規模測試開始。

「大家都直接把管理員密碼給我們」

第一個挑戰是讓 TinyPilot 的訂單系統與 3PL 的系統同步。TinyPilot 使用 Shopify,這是美國最受歡迎的電商平台之一。我們的 3PL 則使用 Shipstation 來管理訂單。Shipstation 相當普及,評價也不錯,因此我原本以為整合 Shopify 與 Shipstation 會輕而易舉。

我的前一家 3PL也有類似的訂單管理系統。要整合時,我只需要在 Shopify 安裝一個應用程式並貼上 3PL 的存取金鑰即可,非常簡單。

當新的 3PL 寄來整合 Shipstation 與我 Shopify 帳號的說明時,他們建議我直接提供 Shopify 的最高管理員帳號密碼,或為他們建立一個新的管理員帳號。

這不可能吧。

我查閱了Shipstation 的說明文件,卻找不到連結兩個帳號的方法。Shipstation 假設 Shopify 帳號與 Shipstation 帳號屬於同一個人,但在我們的情況並非如此。

Shipstation 的設計讓我們陷入僵局。我無法連結到 3PL 的 Shipstation 帳號,因為我沒有他們的 Shipstation 管理員憑證。3PL 也無法連結到 TinyPilot 的 Shopify 商店,因為他們沒有我的 Shopify 管理員憑證。

我不想給 3PL 在 TinyPilot 的 Shopify 上的完整管理員權限,更不想把自己帳號的憑證交出去。

因此,我自行建立了一個 Shipstation 帳號與一個權限受限的虛擬 Shopify 使用者帳號。接著,我反覆嘗試使用這個虛擬帳號,將 TinyPilot 的 Shopify 帳號與我的測試用 Shipstation 帳號連結起來。

經過反覆嘗試,我找出了 Shopify 使用者帳號連結 Shipstation 帳號所需的最少權限。釐清後,我便在 TinyPilot 的 Shopify 中為 3PL 建立了一個僅具備最少必要權限的帳號。

如果有人因為 Shopify 與 Shipstation 的整合問題而找到這篇文章,以下是從 Shopify 端連結 Shipstation 所需的權限:

  • 訂單
    • 編輯訂單
  • 檢視商品
  • 顧客
  • 管理設定
  • 管理與安裝應用程式和管道
用於整合 Shipstation 的 Shopify 使用者權限截圖

使用者連結 Shipstation 帳號所需的最小 Shopify 權限組合

我很驚訝整合 Shopify 與 3PL 的 Shipstation 帳號的過程會如此複雜。3PL 告訴我他們有數十家使用 Shopify 的客戶,於是我詢問他們過去是如何處理這個流程的。

「大家都直接把管理員密碼給我們,」3PL 的經理告訴我。她解釋說,他們大多數客戶對技術不太熟悉,因此不覺得把 Shopify 憑證交給負責出貨的廠商有什麼不妥。

該花 150 美元去寄這筆 50 美元的訂單嗎?

轉移過程中的下一個阻礙,來自一筆來自澳洲的訂單。澳洲是 TinyPilot 服務的國家中運費最高的地區之一。在美國境內寄送一個 TinyPilot Power Connector 只要幾美元,但寄到澳洲卻要 50 美元。

3PL 回報說他們寄送這筆訂單要花 150 美元,但顧客只付了 50 美元。原來,TinyPilot 之所以能享有 DHL 國際運費的優惠價格,是因為 Shopify 代為談到了較好的費率。3PL 並沒有與 DHL 的優惠費率,因此寄到澳洲的郵資必須支付 150 美元。

如果 3PL 以標準郵資寄出,我就得自行吸收 100 美元的差額。這筆訂單會讓我比顧客根本沒下單時還多虧 50 美元。

單筆訂單虧損倒不是什麼大事,但它凸顯了一個更深層的問題。TinyPilot 顧客在結帳時看到的運費是根據 Shopify 的運費費率計算的。我需要讓顧客看到的是 3PL 的運費費率才對。

我又問了一次:「那你們其他客戶都是怎麼處理的?」

3PL 經理說,其他客戶不是提供免運費,就是依國家設定不受包裹大小與重量影響的固定運費。

這樣估算價格雖然不是無法接受,但感覺很草率。我們永遠都在猜測,肯定會出現大幅少收或多收運費的情況。TinyPilot 目前的設定讓顧客能根據精確的運費選擇物流業者,我希望保留這一點。

我從 Shipstation 的文件看到它可以與 Shopify 分享運費費率,因此似乎是可行的。3PL 表示他們從未這樣做過,但願意試試看。幾小時後,3PL 經理打電話告訴我,從 Shipstation 那端是可行的,但我的 Shopify 付費方案並不支援此功能。

我查看了 Shopify 的功能頁面,確認「第三方計算運費」僅在 Shopify 的 Advanced 方案中提供:

Shopify 方案截圖,顯示第三方運費計算僅適用於 Shopify 的 Advanced 方案

Shopify 僅在其每月 399 美元的 Advanced 方案中才會抓取第三方運費費率。

這會讓 TinyPilot 從 Shopify 每月 105 美元的方案,一下子跳到高達每月 399 美元的方案,讓 Shopify 成為 TinyPilot 最昂貴的雲端服務。

當我釐清這一切時,我還在與 3PL 經理通電話。有點衝動地,我當場就升級了方案。

我已經為了運費問題大費周章,當下實在不好意思反悔。不過我刻意選擇月繳方案,以便日後還能改變主意。

回過頭來看,我仍認為 Shopify Advanced 方案是值得的。我真的不想逐一國家估算運費,並隨著市場波動不斷調整。而且我還能透過較高階方案省回一些錢,因為它將信用卡手續費調降 0.2%。以 TinyPilot 去年的營收計算,手續費折扣相當於省下約 2,000 美元,因此至少能補回我每年花在這個昂貴方案上的 4,800 美元中的一部分。

TinyPilot 的需求彈性有多大?

TinyPilot 目前的瓶頸是製造產能。我們仍在內部組裝裝置,但訂單進來的速度幾乎與 TinyPilot 員工組裝的速度相當。

如果要將所有產品都轉移至 3PL,僅僅跟上訂單是不夠的。我們需要額外生產至少一週份量的 Voyager 2a 裝置庫存,送至 3PL 的倉庫。為了放緩銷售速度,我嘗試調漲 TinyPilot 的價格,並獲得了一些有趣的數據。

在經濟學中,產品的「彈性」指的是消費者對價格的敏感程度。Uber 搭乘就是一個富有彈性的產品的例子。如果車資便宜,你會願意為方便付費,但如果價格漲了 10 倍,你大概就會改搭大眾運輸了。

那麼,TinyPilot 的顧客對價格有多敏感呢?

Voyager 2a USB-C

期間價格銷售量
2 月 13 日 - 3 月 6 日$379110 (5.0/天)
3 月 7 日 - 3 月 12 日$39934 (5.7/天)
3 月 13 日 - 3 月 30 日$42965 (3.6/天)
TinyPilot Voyager 2a (USB-C) 價格彈性圖表

Voyager 2a PoE

期間價格銷售量
2 月 13 日 - 3 月 6 日$47829 (1.3/天)
3 月 7 日 - 3 月 12 日$49815 (2.5/天)
3 月 13 日 - 3 月 19 日$5289 (1.3/天)
3 月 20 日 - 3 月 30 日$55813 (1.2/天)
TinyPilot Voyager 2a (PoE) 價格彈性圖表

反思

我的樣本太小,無法做出強而有力的結論,但數據顯示 TinyPilot 顧客對價格的敏感度比我預期的低。PoE 機型的需求似乎特別缺乏彈性,即使我將價格調漲 80 美元(17%),顧客仍以大致相同的速度購買。

我內心的資本家想繼續調漲價格以極大化獲利。我內心的愛好者則想讓一般使用者也能負擔得起。

我最近重讀了自己撰寫關於打造第一代 TinyPilot 原型的部落格文章,注意到這段話:

接著,我研究了商用的 KVM over IP 解決方案。它們提供與 Dell 的 iDRAC 類似的功能,但是……它們甚至更貴,每台要價 500 到 1000 美元。

現在,我自己就成了那個昂貴的商用 KVM over IP 解決方案!

或許有些不理性,但我仍希望 TinyPilot 能提供一款會吸引 2020 年那個只想用簡單方式管理家庭實驗室、又不想花大錢的自己。

我認為在 TinyPilot 同時受限於供應與生產速度的當下,較高的價格是合理的,但我希望未來能再次調降價格,並以銷量來彌補。

舊換新是個笨主意嗎?

每當 TinyPilot 推出新硬體版本,顧客就會詢問是否能將舊裝置換成最新機型。過去,我都告訴他們我們沒有舊換新流程,但會在新版本上提供大幅折扣。

今年,TinyPilot 的主要限制在於Raspberry Pi 的供貨。因此,我正試著在有限的 Pi 供應下,讓 TinyPilot 的收益極大化。

我沒有向顧客提供新裝置的折扣,而是想出了一個自以為聰明的點子:提供舊換新服務。顧客將裝置寄給我們,我們盡可能回收零件並將其轉換為 Voyager 2a,再寄回給顧客。每一款 TinyPilot 產品都使用同一型號的 Raspberry Pi,因此我們能在不消耗任何新 Pi 的情況下回饋忠實顧客。

結果,舊換新流程比我預期的更複雜、也更耗費人力。

許多顧客仰賴 TinyPilot 進行日常工作,因此不想在手邊沒有替代品的情況下寄回裝置。在這些情況下,我們先賣給他們一台由整新零件組成的 Voyager 2a,待收到他們寄回的舊機後再提供部分退款。

還有一些顧客擁有多台 TinyPilot 裝置,且需要全部保持上線。因此,我們會先寄給他們一台整新機,他們再寄回一台舊款裝置,我們將其轉換為最新版本後寄回給他們,接著他們再寄來下一台裝置,如此反覆,直到所有裝置都更換完畢。有些顧客就這樣更換了四台裝置。

所有舊換新作業都順利完成,但工作量遠比我預期的多。

要權衡這個決定的利弊很困難,因為好處是無形的——我們回饋了持續支持我們、想支持產品的顧客。然而,舊換新的缺點卻非常具體。平均而言,舊換新的處理時間比一般銷售多出 2 到 3 倍,而且我們基本上是以成本價進行。

如果 TinyPilot 每筆一般銷售可獲利 300 至 400 美元,而每筆舊換新讓我們少做了約 2.5 筆銷售,那麼每筆舊換新就讓我們損失 750 至 1,000 美元。我們總共做了 22 筆舊換新,因此舊換新方案的成本約為 19,000 美元。

如果重來一次,我仍會提供舊換新,但會做出以下調整:

  • 不要大肆宣傳舊換新,而是與主動詢問的顧客合作。
  • 為舊換新需求設立獨立的客服佇列,並讓顧客預期在開始處理前可能需要等待數週。

業餘專案

以 Go 重寫 Zestful 微服務

回到 2018 年,當我推出 Zestful——我的食譜食材解析服務——時,我希望讓潛在客戶能以低門檻的方式試用服務。其他服務要求你建立帳號或輸入信用卡號,但我想在 Zestful 網站上提供一個無需額外步驟的示範

Zestful 示範頁面截圖

Zestful 提供無需額外步驟的示範,讓潛在客戶測試食材解析功能。

我需要讓示範版將每位使用者限制為每日 30 次解析。超過之後,就必須註冊付費方案。我決定打造一個示範伺服器,其 API 介面與付費伺服器完全相同,差別僅在於將使用者限制為每日 30 項食材。

當時,我非常喜歡 App Engine,也很討厭自行維護資料庫的想法。我使用 Python 2.7 的 App Engine 和 Google Cloud Datastore 撰寫了這個示範應用程式。

當收到請求時,示範伺服器會在 Google Cloud Datastore 中查詢使用者的 IP 位址。如果該 IP 已用完配額,伺服器就會回傳錯誤,要求使用者註冊付費方案。如果使用者仍有剩餘配額,伺服器就會將請求轉發至付費的 Zestful 伺服器,並扣除與該客戶 IP 相關的一單位配額。

自 2018 年以來,我已不再喜愛 App Engine 與 Google Cloud。當我收到 Google 的通知,表示將在幾個月內終止對 Python 2.7 的 App Engine 支援時,我覺得這會是個有趣的實驗,看看如今我能多快重建這個服務。

我沒有使用 Python,而是改用 Go,因為我覺得 Go 的網頁應用程式易於建置與維護。我原本開始思考如何使用 SQLite 與 Litestream 來設計資料庫,直到我意識到其實可以完全省去持久化資料儲存。

如果我把所有人的配額都保留在記憶體中,會有什麼缺點呢?每當我部署新版本或重新啟動伺服器時,所有人的當日配額都會重置,讓他們能在示範伺服器上獲得更多請求額度。

每次重新啟動時多給每位使用者價值 0.60 美元的額外配額並不是什麼大問題,尤其是我本來就打算很少重新啟動伺服器。

我大約花了六個開發時數就重寫了這個服務。我對自己感到很滿意,因為我記得當初花了兩週時間。在短短五年內,我達成了 10 倍的加速!

接著,我回去查看原始 App Engine 版本的提交紀錄,才發現其實我當初只花了一天就完成了。

Mon Apr 30 00:51:48 2018 -0400  Adding badges to README (#7)
Mon Apr 30 00:51:40 2018 -0400  Adding changes to make prod API work (#6)
Mon Apr 30 00:43:55 2018 -0400  Adding support for parser config model (#5)
Sun Apr 29 23:51:03 2018 -0400  Adding deployment to Travis (#4)
Sun Apr 29 23:41:42 2018 -0400  Adding rate limiter (#3)
Sun Apr 29 18:18:37 2018 -0400  Adding coveralls.yml (#2)
Sun Apr 29 18:14:46 2018 -0400  Merge pull request #1 from mtlynch/parser-proxy
Sun Apr 29 18:11:16 2018 -0400  Fixing response handler
Sun Apr 29 17:52:28 2018 -0400  Fixing HTTP handler
Sun Apr 29 17:40:02 2018 -0400  Adding in ParserProxy and tests
Sun Apr 29 11:20:11 2018 -0400  Initial commit

不過,從提交紀錄來看,那似乎是一場從週日早上持續到週一凌晨 1 點的馬拉松式程式撰寫,因此原始版本大概花了約 14 個開發時數。這樣算來,加速幅度其實比較接近 2.3 倍。

所以,我並沒有比五年前快多少,但我很自豪能夠發現一個透過省去資料庫來簡化的新機會。我也很高興自己持續學習新技術,讓自己比過去擁有更多可用的解決方案。

總結

完成了什麼?

  • 將一項產品轉移至 3PL 廠商。
  • NERD Summit 發表演講。
  • 找到新的會計師,並完成 2022 年報稅準備的大部分前置作業。

學到的教訓

  • 在將關鍵作業轉移至新廠商前,先進行小規模試驗。
    • 如果我試圖一次性將所有出貨作業交給 3PL 廠商,情況會變得非常混亂。
    • 從小規模試驗開始,讓我們得以淘汰不合適的第一家廠商,並與第二家廠商磨合細節。

下個月目標

  • 將所有產品轉移至 3PL 廠商。
  • 選定一家委外製造商來接手 TinyPilot 的裝置組裝,並開始轉移流程。
  • 發布新版本的 TinyPilot Pro。

請求協助

如果你或你能說服來與我聊聊的人曾與委外製造商合作過硬體產品,我很樂意聽聽相關經驗。我特別想了解曾以低產量(例如每年 2,000 至 5,000 台)製作電子產品的人的經驗。

原文由 Michael Lynch 發布

本文章由 muse-spark-1.2-contributor 進行翻譯