Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Use Java’s standard StAX API, XMLStreamWriter, to stream a UTF-8 sitemap without assembling one large XML string. Select only canonical, absolute URLs intended for search results, write the Sitemap Protocol namespace and loc values, add lastmod only for significant verifiable changes, then validate and publish the file. A sitemap is a discovery hint—not a guarantee that Google will crawl or index every listed URL.
What a valid sitemap must contain
A web-page sitemap is an XML document with one url element per page:
As an Amazon Associate I earn from qualifying purchases.
- UTF-8 encoding.
- A
urlsetroot in the namespacehttp://www.sitemaps.org/schemas/sitemap/0.9. - A fully qualified absolute URL in each
loc. - Entity-escaped XML character data. The StAX writer escapes character data, but your application must still supply valid, intended URLs.
- An optional
lastmodcontaining a trustworthy date or timestamp for a significant page change.
Do not list every route automatically. Exclude duplicate URL variants, tracking URLs, administrative pages, temporary responses, and pages the site does not want in search results. Prefer the canonical URL when several addresses expose the same content.
Generate a sitemap with Java’s standard library
Streaming writer implementation
This example writes entries as they are iterated, so memory use does not grow with the number of URLs. The caller supplies already-selected canonical URLs and optional change timestamps.
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Instant;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.stream.Stream;
public final class SitemapWriter {
private static final String NS =
"http://www.sitemaps.org/schemas/sitemap/0.9";
public record Entry(String loc, Instant lastModified) {
public Entry {
Objects.requireNonNull(loc, "loc");
if (!loc.startsWith("https://") && !loc.startsWith("http://")) {
throw new IllegalArgumentException("loc must be absolute: " + loc);
}
}
}
public static void write(Path destination, Stream<Entry> entries)
throws IOException, XMLStreamException {
XMLOutputFactory factory = XMLOutputFactory.newFactory();
try (OutputStream out = Files.newOutputStream(destination);
BufferedWriter buffered = new BufferedWriter(
new OutputStreamWriter(out, StandardCharsets.UTF_8))) {
XMLStreamWriter xml = factory.createXMLStreamWriter(buffered);
try {
xml.writeStartDocument("UTF-8", "1.0");
xml.writeStartElement("urlset");
xml.writeDefaultNamespace(NS);
entries.forEach(entry -> {
try {
xml.writeStartElement("url");
xml.writeStartElement("loc");
xml.writeCharacters(entry.loc());
xml.writeEndElement();
if (entry.lastModified() != null) {
xml.writeStartElement("lastmod");
xml.writeCharacters(DateTimeFormatter.ISO_INSTANT
.format(entry.lastModified()));
xml.writeEndElement();
}
xml.writeEndElement();
} catch (XMLStreamException e) {
throw new SitemapWriteException(e);
}
});
xml.writeEndElement();
xml.writeEndDocument();
xml.flush();
} finally {
xml.close();
}
} catch (SitemapWriteException e) {
throw (XMLStreamException) e.getCause();
}
}
private static final class SitemapWriteException extends RuntimeException {
SitemapWriteException(XMLStreamException cause) { super(cause); }
}
}
writeCharacters is preferable to manual string concatenation because the XML writer escapes characters such as &, <, and > in character data. It does not determine whether a URL is canonical, belongs to your site, or is syntactically acceptable, and it does not perform complete well-formedness checking of application input. Validate those policies before writing and validate the finished document afterward.
Calling the writer
try (Stream<SitemapWriter.Entry> entries = loadPublishedPages()) {
SitemapWriter.write(Path.of("sitemap-1.xml"), entries);
}
Keep the stream open until generation completes. If an exception occurs while an entry is being written, discard the partial file rather than publishing it. A production job can write to a temporary path, close and validate it, then atomically rename it to the public filename.
Rank #2
Choose and format lastmod carefully
Use lastmod when you can identify a significant, verifiable change—for example, an edit to the main content, structured data, or important links. A cosmetic copyright-year change is not significant. Omit the field when your timestamp is inferred, stale, or unreliable; inaccurate values reduce its usefulness. Google says it uses lastmod when the value is consistently and verifiably accurate.
The example emits an ISO-8601 instant such as 2026-10-02T12:30:00Z. A date-only value such as 2026-10-02 is also suitable when your data has only calendar-day precision. Use one policy consistently across the site.
Validate before publication
- Check that every
locis an absolute HTTP(S) URL, uses the intended host, and points to the canonical page. - Parse the output with an XML parser or your deployment’s XML validation step to catch unclosed elements, encoding problems, and malformed declarations.
- Confirm the root namespace is exactly
http://www.sitemaps.org/schemas/sitemap/0.9. - Fetch the public URL as an unauthenticated client and verify a successful response, UTF-8 XML content, and no accidental login or redirect loop.
- Measure the uncompressed file and count entries before publishing.
Do not rely on a successful Java write alone: a well-formed XML file can still contain the wrong host, noncanonical URLs, inaccessible pages, or stale metadata.
Stay within sitemap limits
Google’s current guidance (accessed in 2026) limits one sitemap to 50 MB uncompressed or 50,000 URLs. Exceeding either threshold requires multiple sitemap files. Partition deterministically—for example, sort by stable URL or database key and assign fixed batches—so regenerated files do not reshuffle unpredictably.
Rank #4
| Situation | Action |
|---|---|
| At or below both limits | Publish one sitemap file. |
| More than 50,000 URLs or more than 50 MB uncompressed | Split into multiple files and publish an index. |
| Many files or recurring generation | Keep stable partitioning, monitor entry count and byte size, and remove obsolete files from the index. |
Create a sitemap index for multiple files
An index is a separate XML document with a sitemapindex root and one sitemap/loc pair for each sitemap file. Referenced files generally must be on the same site and at the same or a lower directory level than the index; cross-site submission arrangements are an exception. An index can list up to 50,000 sitemap locations. Google says a Search Console property can submit up to 500 sitemap index files.
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>https://example.com/sitemaps/sitemap-1.xml</loc>
</sitemap>
<sitemap>
<loc>https://example.com/sitemaps/sitemap-2.xml</loc>
</sitemap>
</sitemapindex>
Generate the index only after all shard files have passed validation, and publish the index last so it never points at unfinished output.
Best Value
Extensions and alternative formats
Images, video, news, and localized variants
XML supports image, video, news, and other sitemap extensions. Declare each required extension namespace on urlset and emit only the tags allowed by that extension’s current specification. Extension combinations increase validation and maintenance work; do not add fields merely because a library exposes them.
RSS, Atom, and plain text
Google also accepts RSS, mRSS, Atom 1.0, and plain-text sitemap formats. A feed may be simplest when your CMS already maintains one, and a plain-text file can suffice when you only need a list of page URLs. XML is the practical choice when you need sitemap-index structure or extension metadata.
Standard StAX code or a sitemap library?
| Need | Standard-library StAX | Sitemap-specific library |
|---|---|---|
| Dependencies and runtime control | Uses Java’s XML API; no third-party sitemap dependency. | Adds a dependency whose Java/runtime compatibility and maintenance must be checked. |
| Streaming large output | Natural fit: write entries incrementally. | Depends on whether the library streams or builds an in-memory model. |
| URL selection and canonicalization | Your application owns the policy. | Usually still your application’s responsibility; verify what helpers actually enforce. |
| Splitting and index generation | Implement byte/count thresholds and index writing explicitly. | May provide helpers, but confirm both limits and generated namespace output. |
| Extensions | Full control, with more code and validation responsibility. | Convenient only if the needed extension versions are supported and maintained. |
There is no universally authoritative current comparison that establishes a particular Java library as the winner. Choose based on extension requirements, streaming behavior, splitting/index support, and compatibility with your application’s Java version.
Recommended Free Tools
Publish and monitor the file
- Serve the sitemap or index at a stable HTTPS URL.
- In Google Search Console, open the property, choose Sitemaps, enter the sitemap or index URL, and submit it.
- Alternatively, use the Search Console API or add a line such as
Sitemap: https://example.com/sitemap.xmltorobots.txt. - Check the report for the last Googlebot access time and processing errors.
- Keep generation logs for entry count, uncompressed bytes, validation status, and the source-data timestamp.
Google may discover a sitemap from robots.txt on a later crawl. Submission remains a hint: it does not guarantee that Google will download the file or use it to crawl the listed URLs.
Quick Recap
Common failure modes
- Relative URLs: replace paths such as
/aboutwith fully qualified URLs including scheme and host. - Wrong or missing namespace: write the Sitemap Protocol namespace on the root element.
- Unescaped data: write URL values through
writeCharactersand validate the result instead of concatenating XML strings. - Stale
lastmodvalues: omit them until your content system can supply significant-change timestamps. - Oversized output: split on either the 50 MB uncompressed limit or the 50,000-URL limit, whichever comes first.
- Unexpected URLs: review canonicalization, redirects, query parameters, and non-indexable pages before each generation.
- Partial deployment: publish validated shards first and update the index only after every referenced file is available.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




