<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="/assets/xsl/rss.xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<id>https://blog.clew.se/</id>
	<link href="https://blog.clew.se/" rel="alternate" />
	<title>Building Clew</title>
	<subtitle>behind the scenes of independent search</subtitle>
	<rights>© Benjamin Hollon. All posts usable under CC BY-SA 4.0 International.</rights>
	<updated>2026-02-05T17:36:34.213Z</updated>
	
	<author>
		<name>Benjamin Hollon</name>
		<email>me@benjaminhollon.com</email>
		<uri>https://benjaminhollon.com/</uri>
	</author>
	
	
	<entry>
		<id>https://blog.clew.se/posts/secret-web/</id>
		<link href="https://blog.clew.se/posts/secret-web/" hreflang="en" rel="alternate"/>
		<title>A Secret Web</title>
		
		<author>
			<name>Benjamin Hollon</name>
			<email>me@benjaminhollon.com</email>
			<uri>https://benjaminhollon.com/</uri>
		</author>
		
		<summary>The web is mind-bogglingly huge; let&#39;s look at how personal websites can thrive and interact despite that.</summary>
		<content type="html">&lt;p&gt;The web is &lt;a href=&quot;https://googleblog.blogspot.com/2008/07/we-knew-web-was-big.html&quot;&gt;mind-bogglingly massive&lt;/a&gt;. So massive, in fact, that it’s nearly impossibly to visualize its true scale. Even if your entire lifetime was spent perusing the web and searching every nook and cranny, you would never reach more than a miniscule fraction of the vast ocean of information available to you.&lt;/p&gt;
&lt;p&gt;There is so much information in the world that “post-scarcity” is a severe &lt;em&gt;understatement&lt;/em&gt; of the scale of our information age.&lt;/p&gt;
&lt;p&gt;To have any hope of meaningfully browsing the web, we need systems in place that artificially limit that scope—&lt;em&gt;curation&lt;/em&gt; technologies. Today, the web curation process is almost entirely through search engines and social media algorithms, commercial automated systems to narrow our focus on the web to the specific things we know we want.&lt;/p&gt;
&lt;p&gt;Before search engines, though, existed older, more powerful discovery methods, curated by humans for our benefit; these systems and networks still exist, but they seem hidden from the view of the mainstream web.&lt;/p&gt;
&lt;p&gt;Let’s take a look at the secret web, the festival of personal expression and idea sharing happening below the surface, out of the mainstream view, spearheaded by people like you and me.&lt;/p&gt;
&lt;h2&gt;Many Names, One Network&lt;/h2&gt;
&lt;p&gt;Outside the grasp of social media and the commercial web sits a broad community of people with personal websites and blogs, interacting with and following each other without trying to make money or become famous.&lt;/p&gt;
&lt;p&gt;This community has received many names, each trying to capture a different side of the network.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ar.al/2020/08/07/what-is-the-small-web/&quot;&gt;The Small Web&lt;/a&gt; contrasts this community with the “Big Web”, valuing personal ownership over scale.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://indieweb.org/&quot;&gt;The IndieWeb&lt;/a&gt; also values personal ownership of websites, providing numerous technical standards and proposals to help facilitate interaction between different people’s blogs.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://websiteconf.neocities.org/&quot;&gt;Web 1.0&lt;/a&gt; rejects the hype of “Web 2.0” apps, using simple, straightforward technologies to build websites.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Blogosphere&quot;&gt;The Blogosphere&lt;/a&gt; is an old term that’s been around since 1999, referencing the community of bloggers.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiki.melonland.net/web_revival&quot;&gt;The Web Revival&lt;/a&gt; is the concept shared by many that this community has been growing and making a comeback.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Whatever the form, this idea &lt;a href=&quot;https://wiki.melonland.net/manifestos&quot;&gt;keeps coming back&lt;/a&gt;; something appeals to many about the idea of a smaller, more personal web, made up of connections between real people, without corporate interests.&lt;/p&gt;
&lt;p&gt;I call this a “network” because it truly is one; this community of sites has developed many, many ways for readers to discover more of it, and they all revolve around the &lt;a href=&quot;https://en.wikipedia.org/wiki/Hyperlink&quot;&gt;hyperlink&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;The Link Graph&lt;/h2&gt;
&lt;p&gt;The most fundamental innovation of the world wide web as a medium is &lt;em&gt;hypertext&lt;/em&gt; (HTTP, for example, stands for “HyperText Transfer Protocol”). Hypertext, put simply, is text that links to other pages. This is the fundamental technology that ties together the web: every method of discovering sites, other than word of mouth, relies on links between webpages.&lt;/p&gt;
&lt;p&gt;To really understand how these methods work, we need to understand the &lt;em&gt;link graph&lt;/em&gt;. Let’s construct a very tiny subset of the web, made up of just three websites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://benjaminhollon.com/&quot;&gt;benjaminhollon.com&lt;/a&gt; - My personal website&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://joelchrono.xyz/&quot;&gt;joelchrono.xyz&lt;/a&gt; - A friend of mine, who designed the &lt;a href=&quot;https://clew.se/&quot;&gt;Clew&lt;/a&gt; logo&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://neil-clarke.com/&quot;&gt;neil-clarke.com&lt;/a&gt; - The editor of &lt;a href=&quot;https://clarkesworldmagazine.com/&quot;&gt;Clarkesworld Magazine&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Joel and I link to each other’s sites fairly frequently; we talk often and inspire each other. This link is &lt;em&gt;bidirectional&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;While Joel and I both are subscribers to Clarkesworld, I’m the only one who links to Neil Clarke’s blog on my site. Neil Clarke, of course, probably has never encountered my site, so this link is &lt;em&gt;one way&lt;/em&gt;.&lt;/p&gt;
&lt;figure&gt;&lt;img src=&quot;https://blog.clew.se/assets/images/link-graph-example.jpg&quot; alt=&quot;A graph showing links both ways between benjaminhollon.com and joelchrono.xyz and one-way from benjaminhollon.com to neil-clarke.com.&quot; tabindex=&quot;0&quot;&gt;&lt;figcaption&gt;This relationship makes for a simple chart&lt;/figcaption&gt;&lt;/figure&gt;
&lt;p&gt;This is a very simple example of a &lt;em&gt;link graph&lt;/em&gt;, a representation of how various sites link to each other. The more sites you look at, the more complicated it gets; search engines internally graph this relationship between hundreds of thousands, millions, or even billions of sites.&lt;/p&gt;
&lt;p&gt;Given a graph like this, it’s possible to &lt;a href=&quot;https://www.marginalia.nu/log/69-creepy-website-similarity/&quot;&gt;find out how similar sites are&lt;/a&gt;, &lt;a href=&quot;https://en.wikipedia.org/wiki/PageRank&quot;&gt;decide which sites are the most important or official&lt;/a&gt; (one of Google’s key innovations), or predict how a random person surfing the web might discover websites. This concept of the link graph is the most central tool in any analysis of relationships on the web.&lt;/p&gt;
&lt;p&gt;The big difference between the secret web and the large, messy corporate web is that people on it frequently link and reply to each other’s websites and blog posts, creating a compact network of people with related ideas and interests, while on the corporate web companies profit from keeping you on their site and link outwards begrudgingly. This allows projects like &lt;a href=&quot;https://indiemap.org/&quot;&gt;IndieMap&lt;/a&gt;, a link graph of 2,300 sites on the Indie Web and their relationships to each other.&lt;/p&gt;
&lt;h2&gt;Classic Web Discovery: Blogrolls, Link Blogs, and Webrings&lt;/h2&gt;
&lt;p&gt;Now that we understand the importance of links to discovery on the web, let’s examine some classic tools for discovering new sites on the web without search engines.&lt;/p&gt;
&lt;p&gt;One powerful tool is the &lt;strong&gt;blogroll&lt;/strong&gt;—many personal websites have a list of other sites the author finds interesting. This “blogroll” lets readers who enjoy one site easily find a curated list of other sites they’ll enjoy. &lt;a href=&quot;https://benjaminhollon.com/blogroll/&quot;&gt;I have a blogroll&lt;/a&gt;, where I link to all the sites I most closely follow. Many of the blogs I link to also have their &lt;em&gt;own&lt;/em&gt; blogrolls, often larger than mine, providing almost endless opportunity to discover new, fascinating people.&lt;/p&gt;
&lt;p&gt;A tool for discovering sites I’ve personally been enjoying lately is the &lt;strong&gt;link blog&lt;/strong&gt;. Link blogs can either be their own dedicated sites or within a larger blog; the idea is a regular post that links to and comments on interesting articles and webpages the author encountered recently.&lt;/p&gt;
&lt;p&gt;One famous (and fantastic) example is &lt;a href=&quot;https://pluralistic.net/&quot;&gt;Pluralistic&lt;/a&gt;, a daily link blog by &lt;a href=&quot;https://craphound.com/bio/&quot;&gt;Cory Doctorow&lt;/a&gt; focused largely on topics such as digital privacy, monopolistic practices by big tech, environmental sustainability, and right to repair. A recent favorite of mine is &lt;a href=&quot;https://shellsharks.com/scrolls/&quot;&gt;Scrolls&lt;/a&gt;, by &lt;a href=&quot;https://shellsharks.com/about&quot;&gt;Mike Sass&lt;/a&gt;, a weekly roundup of fascinating posts and projects from the IndieWeb and Fediverse.&lt;/p&gt;
&lt;p&gt;Everything old is new again, and &lt;strong&gt;webrings&lt;/strong&gt; are no exception. A webring is a collection of sites who all agree to link to each other in a sort of loop; each site links to two neighbors, and by following the links you reach every site in the ring. Some excellent current examples are the &lt;a href=&quot;https://xn--sr8hvo.ws/&quot;&gt;IndieWeb Webring&lt;/a&gt;, &lt;a href=&quot;https://fediring.net/&quot;&gt;Fediring&lt;/a&gt;, and &lt;a href=&quot;https://polyring.club/&quot;&gt;Polyring&lt;/a&gt; (which I designed the logo for). Often, web rings have a theme, letting people browsing easily surf through many related websites.&lt;/p&gt;
&lt;p&gt;And of course, no discussion of discovery on the web would be complete without mentioning &lt;strong&gt;web feeds&lt;/strong&gt; such as &lt;a href=&quot;https://www.rssboard.org/&quot;&gt;RSS&lt;/a&gt; and &lt;a href=&quot;https://www.ietf.org/rfc/rfc4287.txt&quot;&gt;Atom&lt;/a&gt;, a spam-proof, simple way to subscribe to sites we love to hear about new updates. &lt;a href=&quot;https://aboutfeeds.com/&quot;&gt;About Feeds&lt;/a&gt; is a great introduction, if you’re not already familiar with them.&lt;/p&gt;
&lt;h2&gt;The Danger of Search Engines&lt;/h2&gt;
&lt;p&gt;While all of those wonderful methods for discovering the secret web exist, it’s time to mention the elephant in the room: &lt;strong&gt;search engines&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The selling point of a search engine is essentially to remove the need for you, the reader, to worry about the link graph; when you’re looking for something specific, you can quickly find it without needing to browse numerous websites to get to what you need.&lt;/p&gt;
&lt;p&gt;Search engines are extremely valuable tools, but also bring dangers, if you let them be your &lt;em&gt;only&lt;/em&gt; discovery tool.&lt;/p&gt;
&lt;p&gt;Remember, the web is unimaginably big: you will never see all of it. Any search engine you use will, by necessity, show you a subset of information out there, and the designers have to make decisions about what to value. When a search engine is your sole source of information, you give it full control over what parts of the web, what voices and opinions, even &lt;em&gt;exist&lt;/em&gt; for you.&lt;/p&gt;
&lt;p&gt;With a corporate search engine like Google, that means giving a commercial entity whose main interest is monetary full control over the ideas you receive. From an epistemology standpoint, that should terrify you.&lt;/p&gt;
&lt;p&gt;Even when you start looking at alternate search engines, it’s important to realize that many, such as DuckDuckGo and Ecosia, use the corporate engines’ indexes, under the hood. Mojeek’s &lt;a href=&quot;https://www.searchenginemap.com/&quot;&gt;Search Engine Map&lt;/a&gt; is a good visualization of which engines use their own indexes and which use big tech sources. Seirdy’s &lt;a href=&quot;https://seirdy.one/posts/2021/03/10/search-engines-with-own-indexes/&quot;&gt;article on search engines with independent indexes&lt;/a&gt; is also a fantastic resource.&lt;/p&gt;
&lt;p&gt;All that to say, a search engine cannot be your sole source of information and discovery. Its strength is in helping you find specific things when you need them, but for a well-rounded information gathering experience, we all need to put more faith into other discovery methods, especially for the independent, secret web.&lt;/p&gt;
&lt;h2&gt;New Solutions, Old Concepts&lt;/h2&gt;
&lt;p&gt;I’m certainly not the only one who’s trying to find new discovery methods for the web right now; very, very many others are attaching the same task, and that’s good; &lt;a href=&quot;https://benjaminhollon.com/musings/its-time-to-reinvent-the-wheel/&quot;&gt;reinventing the wheel can be a force for positive change&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;First, I of course am developing an independent search engine that focuses on the small, independent web, &lt;a href=&quot;https://clew.se/&quot;&gt;Clew&lt;/a&gt;. Right now, many others are doing the same or similar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://marginalia-search.com/&quot;&gt;Marginalia&lt;/a&gt; - This is my favorite independent search engine right now, and the one I use the most often.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://unobtanium.rocks/&quot;&gt;Unobtanium&lt;/a&gt; - The developer and I frequently chat about our work and bounce ideas off of each other.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stract.com/&quot;&gt;Stract&lt;/a&gt; - This one launched around the same time as Clew; I haven’t looked too close, though.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lieu.cblgh.org/&quot;&gt;Lieu&lt;/a&gt; - A search engine aimed at searching webrings. Very cool mix of old and new discovery methods!&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mwmbl.org/&quot;&gt;Mwmbl&lt;/a&gt; - A &lt;em&gt;user-curated&lt;/em&gt; search engine, a fascinating experiment.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://searchmysite.net/&quot;&gt;Search My Site&lt;/a&gt; - Very similar in goals to Clew, but only crawls user-submitted sites instead of trying to discover new sites.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://wiby.me/&quot;&gt;Wiby&lt;/a&gt; - A search engine for websites using older technology, great for use on vintage computers.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://yacy.net/&quot;&gt;YaCy&lt;/a&gt; - A decentralized search engine; cool!&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pearsproject.org/&quot;&gt;PeARS&lt;/a&gt; - A search engine that can be run in the browser, without needing a server. I love the concept, and I’m looking forward to seeing it develop.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.mojeek.com/&quot;&gt;Mojeek&lt;/a&gt; - Probably the biggest of the independent search engines; they’ve been around forever.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I’ve also been noticing a few cool new takes on older discovery technologies, many of which I’m considering integrating in some way into Clew. OPML, a format that can list RSS feeds, &lt;a href=&quot;https://opml.org/blogroll.opml&quot;&gt;has a relatively recent proposal for auto-discovering machine-readable blogrolls&lt;/a&gt;, which would be interesting to integrate into crawler code to better find which links on a page are valuable to the site’s creator.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://jamesg.blog/&quot;&gt;James&lt;/a&gt; has been developing a feed reader, &lt;a href=&quot;https://artemis.jamesg.blog/&quot;&gt;Artemis&lt;/a&gt;, and most interesting is a recent integration, &lt;a href=&quot;https://jamesg.blog/2025/03/17/artemis-link-graph&quot;&gt;Artemis Link Graph&lt;/a&gt;, a browser extension that will tell you when a page you’re reading has been linked to by sites you follow. This is an &lt;em&gt;excellent&lt;/em&gt; use of the concept of the link graph, and it would be interesting to integrate this concept into a search engine; perhaps users could specify sites they trust, and the search engine could weight or highlight results appropriately, based on where those sites link?&lt;/p&gt;
&lt;p&gt;I have a few other ideas of my own, and my redesign of Clew has had excellent progress in the last month, so I’m excited to get to publish those ideas relatively soon, probably this summer. It’s a bright world we’re moving into, with amazing ideas for discovering new sites.&lt;/p&gt;
&lt;h2&gt;Preserving and Growing the Secret Web&lt;/h2&gt;
&lt;p&gt;So, we’ve examined how the secret web works, looking at how readers discover new sites and even considering some new, promising ideas. Where do we go next?&lt;/p&gt;
&lt;p&gt;The Secret Web is exciting, and it’s unlikely that it can ever be killed, but it needs intention and attention to really thrive.&lt;/p&gt;
&lt;p&gt;Thankfully, many people are working on the technology side of this; &lt;a href=&quot;https://indieweb.org/&quot;&gt;the IndieWeb&lt;/a&gt;, particularly, is spearheading developing wonderful technology for growing and connecting personal websites.&lt;/p&gt;
&lt;p&gt;With the technical side taken care of, we should consider the social side: much of the independent web today is made up of people with similar interests, in technology in particular. We need to look to lowering the barrier to entry and expanding access to this web. We need to make this web an &lt;em&gt;open&lt;/em&gt; secret.&lt;/p&gt;
&lt;p&gt;There are two sides to this: making it easier to learn to &lt;em&gt;create&lt;/em&gt; websites and easing &lt;em&gt;discovering&lt;/em&gt; websites. In the past, I worked on &lt;a href=&quot;https://readable-css.freedomtowrite.org/&quot;&gt;readable.css&lt;/a&gt;, to ease making beautiful and accessible sites. Now, I’m working on Clew, to make discovering what real people think easier.&lt;/p&gt;
&lt;p&gt;That’s really Clew’s mission: when you look something up, you’re not trying to get to an “official” source of information, you’re looking for blog posts or fan pages about the topic. Very early after releasing Clew, when results were worse than they are today (and, hopefully, &lt;em&gt;much&lt;/em&gt; worse than where they will be soon), the feedback I received was still overwhelmingly positive: even though people weren’t getting the results they’d hoped for, the sites they &lt;em&gt;did&lt;/em&gt; find were fascinating and ones they hadn’t seen before.&lt;/p&gt;
&lt;p&gt;So, what can you, the person reading this do? If you have a website, fantastic! Maybe write some more code towards it, or draft a blog post if you haven’t done so in a while.&lt;/p&gt;
&lt;p&gt;If you think starting a website sounds like fun, you should give it a go! There are very many resources out there. A good starting place is my own guide to &lt;a href=&quot;https://benjaminhollon.com/musings/blogging-on-a-budget/&quot;&gt;blogging on a budget&lt;/a&gt;, where I look at options to have a very personal site without breaking the bank, or even for free.&lt;/p&gt;
&lt;p&gt;And, if you’re interested in finding new, exciting sites from the secret web, perhaps &lt;a href=&quot;https://blogroll.org/&quot;&gt;look through a blogroll&lt;/a&gt;, &lt;a href=&quot;https://82mhz.net/posts/2025/04/linkdump-no-52/&quot;&gt;link blog&lt;/a&gt;, &lt;a href=&quot;https://xn--sr8hvo.ws/directory&quot;&gt;webring&lt;/a&gt;, or &lt;a href=&quot;https://clew.se/&quot;&gt;try searching the web with Clew&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I hope to see you around &lt;a href=&quot;https://benjaminhollon.com/blogroll/&quot;&gt;my corner of my web neighborhood&lt;/a&gt; soon—happy browsing!&lt;/p&gt;</content>
		<updated>2025-05-04T02:34:31.000Z</updated>
		<published>2025-05-04T02:34:31.000Z</published>
	</entry>
	
	<entry>
		<id>https://blog.clew.se/posts/the-new-ariadne-architecture/</id>
		<link href="https://blog.clew.se/posts/the-new-ariadne-architecture/" hreflang="en" rel="alternate"/>
		<title>The New Ariadne Architecture</title>
		
		<author>
			<name>Benjamin Hollon</name>
			<email>me@benjaminhollon.com</email>
			<uri>https://benjaminhollon.com/</uri>
		</author>
		
		<summary>While on a fourteen-hour international flight, I finally managed to come up with an architecture for Clew&#39;s web crawler that I&#39;m happy with. Here&#39;s the run-down.</summary>
		<content type="html">&lt;p&gt;While on a fourteen-hour international flight, I finally managed to come up with an architecture for Clew’s web crawler that I’m happy with. Here’s the run-down.&lt;/p&gt;
&lt;p&gt;The crawler will be split into three main pieces that will run/function independently:&lt;/p&gt;
&lt;h2&gt;ariadne&lt;/h2&gt;
&lt;p&gt;Ariadne is the main process of the web crawler, overseeing tasks and processing data.&lt;/p&gt;
&lt;p&gt;When the task queue is low, Ariadne will select new tasks as needed from the database based on following links, re-crawling pages, checking feeds, and so forth. It will calculate what web requests need to be made and log those to the database, where the other parts will process it.&lt;/p&gt;
&lt;p&gt;Then, from a set of parallelized workers, it will process data from the completed requests as that data comes in. This part of the process is very easily scalable, as I can set how many workers I want to be active at any given time, and each will work in its own process.&lt;/p&gt;
&lt;p&gt;The one crucial difference from the previous architecture: Ariadne will not be making any web requests, itself. It simply decides what requests need to happen and processes the data once they’ve been made.&lt;/p&gt;
&lt;h3&gt;behind the name&lt;/h3&gt;
&lt;p&gt;The name Clew refers to the ball of string used by Theseus to navigate the Labyrinth, an apt metaphor for the difficulty of navigating the web that this search engine tries to ease.&lt;/p&gt;
&lt;p&gt;Ariadne was the woman who wound the clew and gave it to Theseus, and feels like an appropriate name for the web crawler that fetches and organizes the data needed for the engine to be able to find anything.&lt;/p&gt;
&lt;p&gt;Ariadne will continue to be the name for the overall crawler and the user agent it uses when sending requests to sites, to avoid confusion.&lt;/p&gt;
&lt;h2&gt;daedalus&lt;/h2&gt;
&lt;p&gt;Daedalus is the first new part of the crawler’s architecture. Similarly to Ariadne, it will not make any requests itself, but neither will it process any data. Daedalus is, so to speak, a middleman. A manager.&lt;/p&gt;
&lt;p&gt;Daedalus takes items in the task queue that Ariadne generated and collates them into parcels of requests to sites that make sense together. Then, it’ll send this off to individual crawler “nodes” to actually make the requests. This allows me to scale up crawling speeds by having multiple nodes, and even to accept volunteers who want to have their own nodes.&lt;/p&gt;
&lt;p&gt;Daedalus will also handle authentication with those nodes, so that we don’t have malicious nodes poisoning the index data.&lt;/p&gt;
&lt;p&gt;Daedalus is something of a bottleneck, as it can’t be parallelized very well itself, but as it doesn’t actually process any data or make web requests, that &lt;em&gt;shouldn’t&lt;/em&gt; be an issue, at least in the foreseeable future.&lt;/p&gt;
&lt;h3&gt;behind the name&lt;/h3&gt;
&lt;p&gt;Daedalus was the designer of the Labyrinth, a brilliant inventor, and the one who designed and gave Ariadne the clew used by Theseus.&lt;/p&gt;
&lt;p&gt;After Theseus and Ariadne escape, Daedalus and his son, Icarus, are imprisoned by King Minos and escape via wings Daedalus constructs. Unfortunately, Icarus dies in the process.&lt;/p&gt;
&lt;p&gt;Daedalus felt an appropriate name for a process that manages and organizes what needs to be done, as this takes a good deal of logic and inventive skills to decide where to assign tasks.&lt;/p&gt;
&lt;h2&gt;icarus&lt;/h2&gt;
&lt;p&gt;Icarus will be the final piece of the puzzle, a small piece of code that accepts URLs from Daedalus and actually does the fetching of those URLs. It will record the data, probably in the WARC format (which should increase the possibility of collaboration between my crawlers and others in the future), then send that data to Daedalus once it’s collected.&lt;/p&gt;
&lt;p&gt;Icarus is very scalable, as I can host as many nodes of it as I want, even on different machines and possibly hosted by volunteers. Great care will be taken, however to keep from request pages on a single site from multiple Icarus nodes at once, to avoid overloading other people’s servers. This will be part of the logic in Daedalus.&lt;/p&gt;
&lt;h3&gt;behind the name&lt;/h3&gt;
&lt;p&gt;As mentioned, Icarus was Daedalus’s son, which was about the full extent of the logic for naming this section of the code. Icarus’s tragic death from flying too close to the sun, melting the wax holding the feathers to his wings, will &lt;em&gt;hopefully&lt;/em&gt; not be repeated in this project.&lt;/p&gt;
&lt;h2&gt;conclusion&lt;/h2&gt;
&lt;p&gt;And there you have it, the three pieces I plan to construct for my rewrite of Clew’s crawler. I’ve set up the code so that the parts can be easily installed via &lt;code&gt;pipx&lt;/code&gt; and am building CLIs for them, which should ease setup and use of each of the parts. Running a volunteer Icarus node should be as simple as installing the utility, entering your provided authentication key, and running a command to start the process.&lt;/p&gt;
&lt;p&gt;If you’ve got ideas sparked by this, by all means contact me with them! I eagerly await your feedback.&lt;/p&gt;</content>
		<updated>2024-12-14T00:58:29.000Z</updated>
		<published>2024-12-14T00:58:29.000Z</published>
	</entry>
	
	<entry>
		<id>https://blog.clew.se/posts/index-redesign/</id>
		<link href="https://blog.clew.se/posts/index-redesign/" hreflang="en" rel="alternate"/>
		<title>Redesigning the Index</title>
		
		<author>
			<name>Benjamin Hollon</name>
			<email>me@benjaminhollon.com</email>
			<uri>https://benjaminhollon.com/</uri>
		</author>
		
		<summary>I believe I&#39;ve reached a point in Clew&#39;s development where, armed with the knowledge I&#39;ve acquired from months of crawling sites and using that data to search the index, it&#39;s time to wipe the index and start over.</summary>
		<content type="html">&lt;p&gt;I believe I’ve reached a point in Clew’s development where, armed with the knowledge I’ve acquired from months of crawling sites and using that data to search the index, it’s time to wipe the index and start over.&lt;/p&gt;
&lt;p&gt;Why the heck would I do this? Well, my options are either to re-crawl every single site, or to get a fresh start; the latter choice gives a chance to end up with a higher quality index rather than an upgrade of the current one.&lt;/p&gt;
&lt;h2&gt;keeping a record&lt;/h2&gt;
&lt;p&gt;The first big improvement I want to make is to keep a better record of actions the crawler has taken in the past and the results of those actions. This record may not be used or required by the crawler itself, but would make future decisions like this far easier; the crawler can use this record as a cache to generate the new information without having to spam every site in the index to get the information.&lt;/p&gt;
&lt;p&gt;I’d like to implement this using &lt;a href=&quot;https://iipc.github.io/warc-specifications/specifications/warc-format/warc-1.1/&quot;&gt;WARC&lt;/a&gt;, a standard format for archiving webpages that &lt;a href=&quot;https://www.marginalia.nu/log/94_warc_warc/&quot;&gt;Marginalia also uses&lt;/a&gt;. A standard format will be useful both in terms of library support and possible interoperability between crawlers.&lt;/p&gt;
&lt;p&gt;Now, the reason I didn’t implement something like this originally is that I want to be able to publish the index without it becoming a prime source for Machine Learning training; that would be incredibly disrespectful to the sites in Clew’s index. If I keep an archive, it would have to be one that’s optional; that way I can publish the index without the archive and people still use it to self-host their own Clew instances.&lt;/p&gt;
&lt;h2&gt;possible fragmentation of the crawler&lt;/h2&gt;
&lt;p&gt;One of the most requested features upon Clew’s launch was something I wasn’t expecting: many people don’t have the time to contribute code to Clew or money to spare for financial support, but &lt;em&gt;are&lt;/em&gt; willing to contribute bandwidth and computing resources by hosting their own crawler instance.&lt;/p&gt;
&lt;p&gt;With the current architecture of the crawler, this is impossible. In fact, even &lt;em&gt;I&lt;/em&gt; can’t run multiple crawler instances on the same machine.&lt;/p&gt;
&lt;p&gt;If I implemented WARC, however, this would become a possibility. A centralized manager could decide what needs to be crawled, send out a batch of URLs to each crawler instance (volunteer or official), receive WARC replies, then process the information and index it. (“Ariadne@HOME”, anybody?)&lt;/p&gt;
&lt;p&gt;There would have to be some sort of manual vetting of volunteer crawlers and authentication to be sure that there’s no one trying to poison the index, but that’s a bridge that I’m confident can be crossed.&lt;/p&gt;
&lt;h2&gt;more detailed crawling-focused information&lt;/h2&gt;
&lt;p&gt;Currently, the information that ends up in the database is very focused on its relevance to ranking eventual search results. The crawler, however, could really benefit from a couple tables keeping track of its own progress and information needed.&lt;/p&gt;
&lt;h2&gt;better compound keyword detection&lt;/h2&gt;
&lt;p&gt;Compound keywords are something I implemented very early on into Clew’s closed beta. Searching for pages with “Benjamin Hollon” instead of just “Benjamin” and “Hollon” separately gets you far more accurate results, for example.&lt;/p&gt;
&lt;p&gt;The tricky thing was how to know when successive words are compound keywords. I ended up just entering all two-word sequences from every page into the database and hoping it would sort itself out.&lt;/p&gt;
&lt;p&gt;Now, having implemented code using this system, I’ve come up with a better option: take all the two-word sequences, then figure out which are most repeated within each specific page! That way I’m not entering in all the coincidental alignments of filler words into the database and then trying to rank pages based on those words.&lt;/p&gt;
&lt;p&gt;This would also allow me to start doing this with longer sequences; three, four, and even five-word sequences, perhaps. I don’t want to keep track of all five-word sequences, but if the same exact five-word sequence appears multiple times in the same page, it’s probably relevant.&lt;/p&gt;
&lt;h2&gt;tracking overall document language&lt;/h2&gt;
&lt;p&gt;I’ve already been trying to detect a general document language, but I never entered that language into the database; I thought individual keyword languages would be enough. I’ve since discovered it’s not really enough, so I’ll alter this behavior.&lt;/p&gt;
&lt;h2&gt;detection of server ASNs&lt;/h2&gt;
&lt;p&gt;Keeping track of the &lt;a href=&quot;https://en.wikipedia.org/wiki/Autonomous_system_(Internet)&quot;&gt;Autonomous System Number&lt;/a&gt; of servers helps me know what company is providing the hosting. This is helpful to more easily detect spam, better calculate the sustainability impact of pages, and potentially tell the crawler to de-prioritize the crawling of sites hosted with a certain provider or company.&lt;/p&gt;
&lt;p&gt;It could also add the functionality for users to be able to filter out, say, any sites using Cloudflare. Which I know some people using Clew would appreciate the ability to do.&lt;/p&gt;
&lt;h2&gt;evaluation of page/site value&lt;/h2&gt;
&lt;p&gt;Classic Google had “PageRank”, a formula to evaluate the value of a domain name. That strategy has been considered somewhat flawed in retrospect, as publishing a set of criteria which is used to value pages resulted in lots of bad-faith optimization of websites, which is part of why I didn’t originally implement anything like this in Clew.&lt;/p&gt;
&lt;p&gt;I still don’t want to implement any kind of “reputation” feature—the purpose of the engine is to highlight independent and small websites, so that would be counterproductive.&lt;/p&gt;
&lt;p&gt;Still, some kind of rank of how well a site adheres to values I want to reward could be useful. If not for actual result ranking, for crawling purposes. Which brings me to the final point…&lt;/p&gt;
&lt;h2&gt;optimizing crawl order priority&lt;/h2&gt;
&lt;p&gt;This is the most compelling reason to re-crawl from scratch. Given what I know now about the web from the statistics I’ve gathered in the process of crawling it, I can re-optimize the crawler to focus on sites that I’m most interested in crawling. Taking the value score I mentioned above, I can pick which links to follow, prioritizing high-value websites.&lt;/p&gt;
&lt;h2&gt;conclusion&lt;/h2&gt;
&lt;p&gt;I don’t know when I’ll have time to implement this. If I do, I’ll probably leave the current index live on the site so the search engine doesn’t go completely down while I completely redesign the crawler.&lt;/p&gt;
&lt;p&gt;I’m excited about these changes, though, and for the first time in a while I really look forward to having the time to do some work on the crawler.&lt;/p&gt;
&lt;p&gt;I hope you’re excited too. Let me know if you have thoughts or feedback, and see you all in the next update!&lt;/p&gt;</content>
		<updated>2024-11-15T20:52:34.000Z</updated>
		<published>2024-11-15T20:52:34.000Z</published>
	</entry>
	
	<entry>
		<id>https://blog.clew.se/posts/im-losing-faith-in-bm25/</id>
		<link href="https://blog.clew.se/posts/im-losing-faith-in-bm25/" hreflang="en" rel="alternate"/>
		<title>I&#39;m Losing Faith in BM25</title>
		
		<author>
			<name>Benjamin Hollon</name>
			<email>me@benjaminhollon.com</email>
			<uri>https://benjaminhollon.com/</uri>
		</author>
		
		<summary>The current way that result ranking works in Clew is very different from what I want.</summary>
		<content type="html">&lt;p&gt;Up till now, Clew has ranked its results primarily based on the &lt;a href=&quot;https://en.wikipedia.org/wiki/Okapi_BM25&quot;&gt;BM25 algorithm&lt;/a&gt;, a quite brilliant formula for determining the “best match” for a set of keywords out of a set of documents.&lt;/p&gt;
&lt;p&gt;When I first implemented this I was thrilled—not least because I somehow got a complicated math formula working in pure SQL—but as time has gone on I’m less and less pleased with the actual results.&lt;/p&gt;
&lt;aside&gt;
&lt;p&gt;&lt;strong&gt;Nerd alert!&lt;/strong&gt; If you can’t already tell, this update will be rather heavy in technical details. Or, at least, I’ll be going in-depth into the weeds of the math I want to do to rank websites by relevance; you shouldn’t actually need any coding knowledge to understand this post.&lt;/p&gt;
&lt;p&gt;If you feel like sitting this update out, I getcha, skip away without worrying about hurting my feelings. I’ll try and make the next update more entertaining for a wider audience.&lt;/p&gt;
&lt;/aside&gt;
&lt;h2&gt;how things work now&lt;/h2&gt;
&lt;p&gt;I’m gonna try and give a brief overview of what’s going on behind the scenes when the Clew backend is fed a query to help you better contextualize the system I &lt;em&gt;want&lt;/em&gt; to put into place. If you want deeper technical details, do your own research into the algorithm.&lt;/p&gt;
&lt;p&gt;The basic idea behind BM25 is that, given the number of times a word appears in a document (in the case of Clew, &lt;code&gt;&amp;quot;document&amp;quot; == &amp;quot;webpage&amp;quot;&lt;/code&gt;), some basic information about the document, and some information about the word’s frequency overall, you can calculate how well the keyword matches the document.&lt;/p&gt;
&lt;p&gt;For the architecture of Clew, a model like this was a godsend, since it doesn’t require the full text of sites to search, only a &lt;a href=&quot;https://en.wikipedia.org/wiki/Bag-of-words_model&quot;&gt;“bag of words”&lt;/a&gt; linking keywords to documents they appear in.&lt;/p&gt;
&lt;p&gt;The problem arises when a search is for &lt;em&gt;multiple&lt;/em&gt; keywords. With base BM25, you’re instructed to add up the scores for each keyword to get the overall score. In many cases, this works fine; rarer words are weighted more heavily, which keeps words like “the” from being considered more important than “armadillo”. However, an excessive number of &lt;em&gt;occurrences&lt;/em&gt; of a less-important word can outweigh that.&lt;/p&gt;
&lt;p&gt;As an example, take my own name, “Benjamin Hollon”. As of today, searching for my full name on Clew does not actually bring up myself as the first result; instead, it brings up someone whose site doesn’t even &lt;em&gt;mention&lt;/em&gt; “Hollon”, it just says “Benjamin” more times than mine does.&lt;/p&gt;
&lt;p&gt;And that, I think, is the fundamental problem with BM25 for this application: it’s not actually &lt;em&gt;complex&lt;/em&gt; enough.&lt;/p&gt;
&lt;p&gt;Now, don’t get me wrong, I like simplicity. But everything multiplying and adding up to a single score isn’t really suited to a search engine that’s looking at websites from a wide range of authors and web developers.&lt;/p&gt;
&lt;h2&gt;how I want things to work&lt;/h2&gt;
&lt;p&gt;The fundamental principle of the way I &lt;em&gt;want&lt;/em&gt; to rank things is this: some factors are more important than others at an absolute level.&lt;/p&gt;
&lt;p&gt;You see, I’m not limited to sorting by only &lt;em&gt;one&lt;/em&gt; factor. I can say “rank by this, and then if it’s a tie, rank by this other measure”. So, while BM25 will likely remain a component of rankings on Clew, it’ll probably only be a small tiebreaker for when the methods I’m about to describe fail.&lt;/p&gt;
&lt;p&gt;The primary factor I want to rank by is the &lt;em&gt;completeness&lt;/em&gt; of a match. What do I mean by that?&lt;/p&gt;
&lt;p&gt;Well, let’s start with a simple model. In a search for “Benjamin Hollon”, a match is 50% complete if it only has &lt;em&gt;either&lt;/em&gt; “Benjamin” &lt;em&gt;or&lt;/em&gt; “Hollon”. It must contain both to be a 100% match.&lt;/p&gt;
&lt;p&gt;But, of course, a match containing only “Hollon” is more likely to be relevant, since it’s a relatively uncommon surname, while “Benjamin” is a fairly common given name, so in reality, perhaps it should be 30% and 70%.&lt;/p&gt;
&lt;p&gt;And, to take it further, if “Benjamin” and “Hollon” appear in separate paragraphs, that’s less complete a match than a site with “Benjamin Hollon” in order.&lt;/p&gt;
&lt;p&gt;I want to make code to take a query, extract the keywords, weigh the keywords relative to each other, and then be able to calculate given a result how &lt;em&gt;complete&lt;/em&gt; the match is.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;If one result is more complete a match than another, it gets ranked higher, &lt;em&gt;no further questions asked&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Next, if a site has invasive ads or tracking, I want it to be ranked lower than any equally-complete matches &lt;em&gt;without&lt;/em&gt; ads or tracking.&lt;/li&gt;
&lt;li&gt;I haven’t decided yet, but I could decide to rank sites using &lt;code&gt;https://&lt;/code&gt; higher than sites with &lt;code&gt;http://&lt;/code&gt; if both of the above are tied&lt;/li&gt;
&lt;li&gt;I want to take BM25 into account at this point to break remaining ties, but probably weighted with some other factors I also care about at around the same level, perhaps including my handy-dandy page size scores&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Why put BM25 so low? Well, to put it simply… it’s a very easily-spoofed scoring system. I can say the word “armadillo” over and over on one page of my website to artificially boost how relevant that term looks to the BM25 algorithm. And while I haven’t seen any cases of this being done maliciously, I have seen times where the way a site was designed meant a word was repeated more often on one site than another.&lt;/p&gt;
&lt;h2&gt;conclusion&lt;/h2&gt;
&lt;p&gt;If you’ve made it to the end of today’s incoherent ramblings, congratulations! I may sound very intelligent and bright at this point, but it remains to be seen whether I can actually manage to &lt;em&gt;implement&lt;/em&gt; this grand vision and, perhaps more crucially, whether I can implement it without sacrificing performance.&lt;/p&gt;
&lt;p&gt;Future updates to this blog probably won’t be as technical; mainly I couldn’t sleep and needed to write my thoughts down to calm down my inner monologue, who is kinda bossy.&lt;/p&gt;
&lt;p&gt;See you next time, you glorious nerds.&lt;/p&gt;</content>
		<updated>2024-06-27T15:41:48.000Z</updated>
		<published>2024-06-27T15:41:48.000Z</published>
	</entry>
	
	<entry>
		<id>https://blog.clew.se/posts/welcome-to-the-madness/</id>
		<link href="https://blog.clew.se/posts/welcome-to-the-madness/" hreflang="en" rel="alternate"/>
		<title>Welcome to the Madness</title>
		
		<author>
			<name>Benjamin Hollon</name>
			<email>me@benjaminhollon.com</email>
			<uri>https://benjaminhollon.com/</uri>
		</author>
		
		<summary>In which we launch the insanity that is this development blog for Clew.</summary>
		<content type="html">&lt;p&gt;After a while of developing Clew I realized it would probably be a good idea to start a development blog so that you can trace the collapse of my sanity in real time (why are emojis allowed in URLs anyway??? 😩).&lt;/p&gt;
&lt;h2&gt;what to expect&lt;/h2&gt;
&lt;p&gt;I have no idea. We’ll have to figure it out together. I’ll probably post progress updates here, so you can be sure that I’m not just spending my days eating chips and playing video games instead of reinventing the wheel like I’m &lt;em&gt;supposed&lt;/em&gt; to. Perhaps the occasional announcement.&lt;/p&gt;
&lt;p&gt;If nothing else, I plan to try and make it entertaining. So hey, follow along. There’s an &lt;a href=&quot;https://blog.clew.se/&quot;&gt;Atom Feed&lt;/a&gt; to get updates as they come out, and if you don’t know what that means, read &lt;a href=&quot;https://hunden.linuxkompis.se/2020/07/29/an-introduction-to-web-feeds.html&quot;&gt;this excellent post by Hund&lt;/a&gt; (#DiscoveredWithClew) to learn all about it.&lt;/p&gt;
&lt;h2&gt;current status&lt;/h2&gt;
&lt;p&gt;So as not to leave you empty handed, here’s a quick update on what’s going on right now.&lt;/p&gt;
&lt;p&gt;I just finished coding a multithreaded, multi-queue task prioritization system for Ariadne, Clew’s crawler, and somehow (&lt;em&gt;somehow&lt;/em&gt;) it worked first try. With that out of the way, I’ve set the crawler running on my server and the index is steadily growing.&lt;/p&gt;
&lt;p&gt;There’s still a little work to do before releasing the crawler’s code publicly on &lt;a href=&quot;https://codeberg.org/Clew&quot;&gt;Clew’s Codeberg organization&lt;/a&gt;, but this was the biggest blocker to getting that done, so it shouldn’t be long now, assuming no mental breakdowns on my side.&lt;/p&gt;
&lt;p&gt;Once that’s all wrapped up and the crawler is running at full speed, I’ll be starting work on a refactor of the query parsing and matching logic for searches.&lt;/p&gt;
&lt;p&gt;You see, one of the current issues with Clew is that it can rank how &lt;em&gt;strong&lt;/em&gt; matches are given keywords, but it doesn’t actually have a way to gauge whether a result actually fully matches. For example, &lt;a href=&quot;https://clew.se/search?q=benjamin+hollon&quot;&gt;a search for “benjamin hollon”&lt;/a&gt; could have a page that just says “benjamin” over and over at the top, even if it never says “hollon”, because the &lt;em&gt;strength&lt;/em&gt; of the match for “benjamin” is so high.&lt;/p&gt;
&lt;p&gt;Once this refactor is finished, results will first be sorted by the completeness of the match, &lt;em&gt;then&lt;/em&gt; by the strength results match the keywords with.&lt;/p&gt;
&lt;p&gt;It sure won’t be easy, but it should drastically improve the results you get when using Clew.&lt;/p&gt;
&lt;h2&gt;bye&lt;/h2&gt;
&lt;p&gt;Okay, I need to get back to bashing my head against the brick wall that is the Clew codebase. See you next time!&lt;/p&gt;</content>
		<updated>2024-06-22T00:35:43.000Z</updated>
		<published>2024-06-22T00:35:43.000Z</published>
	</entry>
	
</feed>
